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).
© 版权声明
文章版权归作者所有,未经允许请勿转载。




那个 range 边界确定没写错?少加个 1 就废了。
边界少1就全错,建议加个注释说明推导过程。
作业题吧?看着像信科专业的硬核内容。
概率飙升得太快,直觉完全跟不上数学。
要是人数超过 365 咋办,公式还成立不?
365 天忽略闰年,这假设在实际里准吗?🤔
之前算阶乘直接爆内存,加个 log 确实稳。
log真是救命稻草,我上次算到100!直接崩了。
变量名起得太随意了,up 和 dr 啥意思啊?
up是累加分子的对数和吧,dr应该是分母?
r=0 不就是经典生日悖论吗,23 人确实过半。
这公式看着头大,代码倒是能跑通。
up和dr变量名也太抽象了,读着费劲
直接算阶乘肯定溢出啊,我之前试过😂
这种计算用Stirling近似会不会更快点?
r=2的时候概率这么高?感觉有点反直觉。
老哥这代码写得够简洁,变量名省事。
看到那个88%的概率,突然觉得巧合也没那么巧了。
GitHub链接能贴一下不?想跑跑看结果。
这作业看着有点硬核啊,概率论早还给老师了。
原来是用log避免溢出,我说怎么直接算阶乘老是报错。
那个range的边界看得我有点迷糊,365-n*r确定不用+1?
r=0不就是经典生日悖论吗,23人确实过半。
这代码跑起来倒是挺快,就是公式看着眼晕。
之前搞过类似计算,阶乘太大不用log根本存不下
求问这个log转换是不是必须的?直接算会炸吗?
对数防溢出,写代码时这招挺常用
确实,防溢出必备
直接用对数处理大数,这法子挺巧的
确实,避免溢出的好办法
对数方法防溢出挺实用的
代码排版可以再优化下
同感,看着有点乱
对数变换这思路不错
确实很实用
算得挺快,结果一目了然
这个公式推导过程能展开讲讲吗?
对数计算这块写得蛮清楚
对,用对数处理确实清晰
概率论作业刚好用上了,帮大忙了!
对数处理防溢出这招挺实用
确实,处理大数时常用这招
M1芯片上试了,跑得飞快,没问题。
这结果说明生活中很多“巧合”其实概率挺高的?
完全看不懂,就当看个热闹吧。
之前写作业也卡在这题,用对数转换是标准解法了。
变量名起得也太随意了,up和dr完全猜不出意思。
这代码跑起来快吗?会不会有性能瓶颈?
r=2的概率高得有点吓人,现实里真这么准?
用log算阶乘确实巧妙,避免了溢出问题。
range边界确实容易写错,debug了好几次。
之前也卡在阶乘计算上,加个log确实管用
r=2时50人概率接近1?这也太吓人了
GitHub链接啥时候公开?想跑跑看
23个人就过半概率?比想象中少多了
吃个瓜,数学渣表示完全看不懂🍉
变量名up和dr是啥意思?太抽象了
用log确实稳,之前算阶乘内存炸过好几次
这公式看着头大,不过代码实现倒是挺巧妙的😂