生日悖论

计算生日悖论概率

假设一个班级有n个人,那么计算这n个人至少有两个人生日相同的概率。
一般情况下,我们感性认识上会觉得班级上至少有两个人生日相同的概率会比较低,毕竟每个人的生日有365种选择,而班级一半只有30人左右,但是实际上计算得到的至少两人生日相同的概率却远远大于我们的感性认识,所以称为生日悖论。

计算生日概率

假设班级有n个人,我们从反面计算至少有两个人生日相同的概率,这个反面就是每个人生日都不同的概率。那么这个概率可以这么计算:
1. 第一个同学的生日有365种选择;
2. 第二的同学的生日有364种选择,这里是因为要保证每个人的生日都不同,所以已经选择过的日期不能再选。
3. 第三个同学的生日有363种选择;
4. 第四个同学的生日有362种选择;
5. 第i个同学的生日有365 - i + 1种选择;

这n位同学的总的选择的数量为:

i=1n365=365n

所以,假设班级上n为同学的生日都不相同的概率为:

prob(n)=i=1n(365i+1)365

然后,包含n位童鞋的一个班级,至少有两个童鞋生日相同的概率为:

p=1prob(n)

替换公式种的生日不同的概率公式prob(n):

p=1prob(n)=1i=1n(365i+1)365

来看看至少有两个人生日相同的概率

假设n = 30, (班级有30个人),那么,至少有两个人生日相同的概率为:
p(30) = 0.706316242719

n = 24,
p(24) = 0.507297234324
当班级内人数超过24人后,至少有两人生日相同的概率就已经超过了0.5

代码来啦

代码中,为了防止浮点数连成造成数据溢出,采用了log加法的方式进行计算。

#!/usr/bin/env python
"""
Given a number of people, compute the probability of at least two people have the same birthday
"""

import math

class Solution(object):
    def computeProb(self, n):
        """
        :type n: int
        :rtype: float


        Idea: if n > 365, then definitely at least two people will has the same birthday,
        when n <= 365, we compute the probability of that these people do not have same birthday,
        1th people have 365 choice, 2nd people has 364 choice, 3rd people has 363 choice, etc.

        Using log operation to avoid float multipy overflow
        """

        assert n > 0, 'n should > 0'

        if n > 365:
            return 1.0

        prob = 0.0
        for i in xrange(n):
            prob += math.log((365 - i) / 365.0, 2)

        return 1.0 - 2.0 ** prob

class BirthdayParadoxImage(object):
    def showCurve(self):
        x = [i + 1 for i in range(365)]
        y = []

        prob = 0.0
        for n in x:
            prob += math.log((365 - n + 1) / 365.0, 2)

            current_prob = 1.0 - 2.0 ** prob
            y.append(current_prob)

        import matplotlib.pyplot as plt 
        plt.title('probability of at least two people have the same birthday')
        plt.plot(x, y, color='blue', lw=2)
        plt.show()

if __name__ == '__main__':
    so = Solution()

    print so.computeProb(20), ', probability of 20 people'
    print so.computeProb(23), ', probability of 23 people'
    print so.computeProb(40), ', probability of 40 people'
    print so.computeProb(364), ', probability of 364 people'
    print so.computeProb(365), ', probability of 365 people'
    print so.computeProb(400), ', probability of 400 people'

    print 'show curve'
    image = BirthdayParadoxImage()
    image.showCurve()

生日悖论曲线

来看看当班级人数增加时,至少有两个人生日相同的概率是如何变化的:
这里写图片描述

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值