算法导论 练习5.4-4

一次聚会需要邀请多少人,才能让其中3人的生日很可能相同?

为了便于叙述,对题目作一个转化:

考虑将n粒豆子随机放入365个桶中,至少有一个桶内豆子数量不少于3的概率,其中豆子、桶均有区别

因为豆子和桶均有区别,可得全事件的数量为365^n

豆子放入完成后,桶内至多有一粒豆子的情况相当于从365个桶中选取n个,并将n粒不同豆子依次放入,因此事件数为:

C_{365}^{n} \cdot A_{n}^{n}

仅有一个桶内有两粒豆子,其余均为一粒或没有。这里我们首先考虑从n粒豆子中选出两粒绑定在一起,进而转化为从365个桶中选取n-1个,将豆子依次放入,事件数为:

C_{365}^{n - 1} \cdot C_{n}^{2} \cdot A_{n - 1}^{n - 1}

有且仅有i个桶内有两粒豆子,其余均为一粒或没有。这里有一点需要注意的是绑定豆子的顺序问题,即先绑定豆子[1, 2],后绑定豆子[3, 4]与先绑定[3, 4]后绑定[1, 2]是相同的,因此在绑定后需除以排列数。事件数为:

C_{365}^{n - i} \cdot (\prod_{k = 0}^{i - 1}C_{n - 2k}^{2}) / A_{i}^{i} \cdot A_{n - i}^{n - i}

从全事件中去除上述事件后,剩余事件占全事件的比例即为至少一桶内有不少于3粒豆子的概率,实现如下:

from math import factorial
import numpy as np

class Birthday:
    def C(self, a, b):
        return factorial(a) / factorial(a - b) / factorial(b)
    def A(self, a, b):
        return factorial(a) / factorial(a - b)
    def slove(self, n):
        if n < 3:
            return 0
        elif n > 730:
            return 1
        elif n < 366:
            pair = int(n / 2)
            p = (self.C(365, n) * self.A(n, n) + sum(self.C(365, n - i) * np.prod([self.C(n - 2 * k, 2) for k in range(i)]) / self.A(i, i) * self.A(n -i, n- i) for i in range(1, pair + 1))) / 365**n
            return 1 - p
        else:
            # 估计用不上,计算量太大
            pair = int(n / 2)
            return 1 - sum(self.C(365, n - i) * np.prod([self.C(n - 2 * k, 2) for k in range(i)]) / self.A(i, i) * self.A(n -i, n- i) for i in range(1, pair + 1)) / 365**n

if __name__ == '__main__':
    bir = Birthday()
    bir.slove(30)   # 0.0285
    bir.slove(50)   # 0.1264
    bir.slove(80)   # 0.4182
    bir.slove(87)   # 0.4995
    bir.slove(88)   # 0.5111
    bir.slove(120)  # 0.8280

可以看出,88人时,有三人生日相同的概率即超过0.5

此处答案与使用期望计算略有不同,个人认为是因为期望计算时包含了部分重复导致

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值