生日悖论

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Harrytsz/article/details/83859900

计算生日悖论概率

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

计算生日概率:

假设班级有n个人,我们从反面计算至少有两个人生日相同的概率,这个反面就是每个人生日都不同的概率。那么这个概率可以这么计算:

  1. 第一个同学的生日有365种选择;
  2. 第二的同学的生日有364种选择,这里是因为要保证每个人的生日都不同,所以已经选择过的日期不能再选。
  3. 第三个同学的生日有363种选择;
  4. 第四个同学的生日有362种选择;
  5. 第i个同学的生日有365 - i + 1种选择;

这n位同学的总的选择的数量为:
i = 1 n 365 = 36 5 n \prod_{i=1}^{n}365 = 365^{n}

所以,假设班级上 n 位同学的生日都不相同的概率为:
p r o b ( n ) = i = 1 n 365 i + 1 365 prob(n) = \prod_{i=1}^{n} \frac{365-i+1}{365}

然后,包含 n 位同学的一个班级,至少有两位同学生日相同的概率为:
p = 1 p r o b ( n ) p = 1 - prob(n)

替换公式中的生日不同的概率公式 p r o b ( n ) : prob(n):
p = 1 p r o b ( n ) = 1 i = 1 n 365 i + 1 365 p = 1 - prob(n) = 1 - \prod_{i=1}^{n} \frac{365-i+1}{365}

所以 n 位同学中至少有两位生日相同的概率:

n 10 15 20 25 30 35 40 45 50
P 0.12 0.25 0.41 0.57 0.71 0.81 0.89 0.94 0.97

代码如下:

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 range(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='red', lw=1)
        plt.grid(b=True)
        plt.show()

if __name__ == '__main__':
    so = Solution()
    print(str(so.computeProb(10)) + ', probability of 10 people')
    print(str(so.computeProb(15)) + ', probability of 15 people')
    print(str(so.computeProb(20)) + ', probability of 20 people')
    print(str(so.computeProb(25)) + ', probability of 25 people')
    print(str(so.computeProb(30)) + ', probability of 30 people')
    print(str(so.computeProb(35)) + ', probability of 35 people')
    print(str(so.computeProb(40)) + ', probability of 40 people')
    print(str(so.computeProb(45)) + ', probability of 45 people')    
    print(str(so.computeProb(50)) + ', probability of 50 people')
    
    print('show curve')
    image = BirthdayParadoxImage()
    image.showCurve()

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Harrytsz/article/details/83859900