1,619字
7–10 分钟
Problem Description
Generalized Birthday Problem: Consider people in a room. Assume each person’s birthday is equally likely to be any of the 365 days of the year (ignoring February 29), and all birthdays are independent. When and satisfy certain conditions, the probability that at least two people have birthdays within days of each other is:
Implementation
This is a simple code using Log-Probability Computation to calculate . The logarithmic transformation helps prevent numerical overflow and reduces computation errors when dealing with large factorials.
import math
ln = math.log
def calculateP(n, r):
up = 0
dl = (n - 1) * ln(365)
dr = 0
for i in range(1, 365 - n * r):
up += ln(i)
for j in range(1, 365 + 1 - r * n - n):
dr += ln(j)
right = math.exp(up - dl - dr)
return 1 - right
print(calculateP(10, 0))
print(calculateP(20, 0))
print(calculateP(23, 0))
print(calculateP(30, 0))
print(calculateP(40, 0))
print(calculateP(50, 0))
print()
print(calculateP(10, 1))
print(calculateP(20, 1))
print(calculateP(23, 1))
print(calculateP(30, 1))
print(calculateP(40, 1))
print(calculateP(50, 1))
print()
print(calculateP(10, 2))
print(calculateP(20, 2))
print(calculateP(23, 2))
print(calculateP(30, 2))
print(calculateP(40, 2))
print(calculateP(50, 2))
Code language: Python (python)
Results
| n | r=0 | r=1 | r=2 |
|---|---|---|---|
| 10 | 0.1169481777 | 0.3147165301 | 0.4720877238 |
| 20 | 0.4114383836 | 0.8044833552 | 0.9393140224 |
| 23 | 0.5072972343 | 0.8879096437 | 0.9770852403 |
| 30 | 0.7063162427 | 0.9781953620 | 0.9987474258 |
| 40 | 0.8912318098 | 0.9991154417 | 0.9999963536 |
| 50 | 0.9703735796 | 0.9999879831 | 0.9999999989 |
Source
This code is used to solve a problem in the homework of Probability and Statistics for Information Science course. You can find the complete assignment in my GitHub repository (The visibility will be changed to public after the course ends).
© 版权声明
文章版权归作者所有,未经允许请勿转载。




这不就是生日悖论扩展版嘛,懂了懂了。
up和dr是上界下界?起名能不能走点心。
r=2时50人概率快1?这也太吓人了。
看不懂公式,吃个瓜🍉
这种计算用 Stirling 近似会不会更快点?
跑个50人r=2直接99.9%,吓我一跳
r=2的时候50个人概率都快到1了,挺反直觉的
第一次看的时候我也觉得离谱
23 个人就过半了?以前总觉得得更多人呢。
用对数防溢出这招真灵,不然阶乘早炸了
跑出来结果跟理论值一致,稳
跑通看到结果对上的瞬间确实爽
这代码变量名看得我头大,up 到底是啥?
对数处理大数这个思路挺巧妙的
确实,避免数值溢出了
23人r=0概率0.507,跟经典结论对上了
r=2才隔两天,五十个人几乎必中?太邪门了。
这代码能用吗?我试了下报错
看不懂公式,但看结果觉得人类巧合也太频繁了。
这代码跑出来结果跟理论值差多少?
我也想知道误差多大
之前搞过这个,确实折腾了好久才想到用log。
概率涨这么猛,现实里真有这么多人撞生日?
log处理确实聪明,不然大数直接炸穿。
要是n大于365还成立吗?感觉边界有点悬。
r=0时23人过半,课本里经典结论终于见着了。
这公式看着就头大,数学渣表示告辞。
公式一出来我就想关页面了,救命😭
信科作业都这么硬核了吗?😂
那个 range 边界确定没写错?少加个 1 就废了吧。
用 log 转换确实稳,之前我也在这坑里栽过。
数学渣路过,光看结果觉得挺神奇。
忽略闰年影响大吗?还是说随便估个近似值就行?
23 人过半概率,经典生日悖论没跑了。
变量名 up 和 dr 是啥意思?看着太抽象了。
直接算阶乘肯定爆内存,亲测过。
r=2 时概率快 100% 了?这有点反直觉啊。
那个range的边界条件确定没写错吗?看着有点悬。
数学渣表示完全看不懂,但感觉好厉害的样子😂
求问这个在M1芯片的Mac上能跑吗?
代码能跑就行,变量名无所谓啦。
之前搞过类似的计算,确实得用对数,不然数字太大。
这公式看着就头疼,不过结果挺有意思。
看不懂,吃个瓜。
r=2的时候概率这么高?有点超出直觉了。
用log确实聪明,之前直接算阶乘内存直接炸了。
代码里的变量名太抽象了,up和dr是啥?
不用 log 根本存不下大数,亲测过😂
直接算阶乘内存爆炸,我上次跑崩三台虚拟机😂