Python Code for Computing Generalized Birthday Problem

专业相关2026年3月20日发布 芮和
15.7K 1080
1,619字
7–10 分钟

Problem Description

Generalized Birthday Problem: Consider nn 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 nn and rr satisfy certain conditions, the probability that at least two people have birthdays within rr days of each other is:

P=1(3651nr)!365n1(365(r+1)n)!P=1-\frac{(365-1-n r)!}{365^{n-1}(365-(r+1) n)!}

Implementation

This is a simple code using Log-Probability Computation to calculate PP. 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

nr=0r=1r=2
100.11694817770.31471653010.4720877238
200.41143838360.80448335520.9393140224
230.50729723430.88790964370.9770852403
300.70631624270.97819536200.9987474258
400.89123180980.99911544170.9999963536
500.97037357960.99998798310.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).

© 版权声明

相关文章

108 条评论

  • 咋咋唬
    咋咋唬 游客

    这不就是生日悖论扩展版嘛,懂了懂了。

    中国广东
    回复
  • 星尘漫步
    星尘漫步 游客

    up和dr是上界下界?起名能不能走点心。

    中国北京
    回复
  • 傲视苍穹
    傲视苍穹 游客

    r=2时50人概率快1?这也太吓人了。

    中国辽宁
    回复
  • 渊回
    渊回 游客

    看不懂公式,吃个瓜🍉

    中国江苏
    回复
  • 豆豆鼠
    豆豆鼠 游客

    这种计算用 Stirling 近似会不会更快点?

    韩国
    回复
  • 星空观测者
    星空观测者 读者

    跑个50人r=2直接99.9%,吓我一跳

    韩国
    回复
  • JellybeanJoy
    JellybeanJoy 读者

    r=2的时候50个人概率都快到1了,挺反直觉的

    中国上海
    回复
    • 社会边界
      社会边界 读者

      第一次看的时候我也觉得离谱

      中国陕西@ JellybeanJoy
      回复
  • 战意无双
    战意无双 读者

    23 个人就过半了?以前总觉得得更多人呢。

    中国台湾
    回复
  • 幽梦织影
    幽梦织影 读者

    用对数防溢出这招真灵,不然阶乘早炸了

    美国
    回复
  • ColdFire
    ColdFire 读者

    跑出来结果跟理论值一致,稳

    中国广东
    回复
    • 旧日影集
      旧日影集 读者

      跑通看到结果对上的瞬间确实爽

      巴西@ ColdFire
      回复
  • Pearl of Dawn
    Pearl of Dawn 游客

    这代码变量名看得我头大,up 到底是啥?

    韩国
    回复
  • 幽冥织梦
    幽冥织梦 读者

    对数处理大数这个思路挺巧妙的

    韩国
    回复
    • 硅基先知
      硅基先知 读者

      确实,避免数值溢出了

      中国重庆@ 幽冥织梦
      回复
  • 月光柠檬
    月光柠檬 读者

    23人r=0概率0.507,跟经典结论对上了

    美国
    回复
  • PawsTheExplorer
    PawsTheExplorer 游客

    r=2才隔两天,五十个人几乎必中?太邪门了。

    中国吉林
    回复
  • 愤怒的画家
    愤怒的画家 读者

    这代码能用吗?我试了下报错

    美国
    回复
  • 旧时风月
    旧时风月 读者

    看不懂公式,但看结果觉得人类巧合也太频繁了。

    中国广东
    回复
  • 礼部郎中
    礼部郎中 读者

    这代码跑出来结果跟理论值差多少?

    美国
    回复
    • 零点星链
      零点星链 读者

      我也想知道误差多大

      中国山东@ 礼部郎中
      回复
  • 快乐星球管理员
    快乐星球管理员 游客

    之前搞过这个,确实折腾了好久才想到用log。

    中国湖北
    回复
  • 云朵贝
    云朵贝 读者

    概率涨这么猛,现实里真有这么多人撞生日?

    中国河南
    回复
  • 语晴
    语晴 游客

    log处理确实聪明,不然大数直接炸穿。

    印度
    回复
  • 农夫田七
    农夫田七 读者

    要是n大于365还成立吗?感觉边界有点悬。

    日本
    回复
  • 芝士雪豹
    芝士雪豹 游客

    r=0时23人过半,课本里经典结论终于见着了。

    中国山东
    回复
  • 雾隐之刃
    雾隐之刃 游客

    这公式看着就头大,数学渣表示告辞。

    巴基斯坦
    回复
    • Driftwood
      Driftwood 游客

      公式一出来我就想关页面了,救命😭

      中国河北@ 雾隐之刃
      回复
  • 智鸦谜语
    智鸦谜语 读者

    信科作业都这么硬核了吗?😂

    中国湖南
    回复
  • 兰陵郡主
    兰陵郡主 读者

    那个 range 边界确定没写错?少加个 1 就废了吧。

    中国吉林
    回复
  • 阳台种番茄
    阳台种番茄 读者

    用 log 转换确实稳,之前我也在这坑里栽过。

    日本
    回复
  • 木婉清
    木婉清 游客

    数学渣路过,光看结果觉得挺神奇。

    中国吉林
    回复
  • 夜风轻语
    夜风轻语 游客

    忽略闰年影响大吗?还是说随便估个近似值就行?

    中国陕西
    回复
  • 卡魔拉
    卡魔拉 游客

    23 人过半概率,经典生日悖论没跑了。

    中国陕西
    回复
  • 爱偷懒的南瓜
    爱偷懒的南瓜 游客

    变量名 up 和 dr 是啥意思?看着太抽象了。

    中国北京
    回复
  • 优奈花音
    优奈花音 游客

    直接算阶乘肯定爆内存,亲测过。

    中国陕西
    回复
  • 银河远航
    银河远航 游客

    r=2 时概率快 100% 了?这有点反直觉啊。

    中国广东
    回复
  • 反内卷大队长
    反内卷大队长 游客

    那个range的边界条件确定没写错吗?看着有点悬。

    中国北京
    回复
  • TideDancer
    TideDancer 游客

    数学渣表示完全看不懂,但感觉好厉害的样子😂

    中国内蒙古
    回复
  • 星星发夹
    星星发夹 游客

    求问这个在M1芯片的Mac上能跑吗?

    日本
    回复
  • 茉莉眠
    茉莉眠 读者

    代码能跑就行,变量名无所谓啦。

    中国四川
    回复
  • 黑山魈
    黑山魈 游客

    之前搞过类似的计算,确实得用对数,不然数字太大。

    新加坡
    回复
  • 影之织梦
    影之织梦 读者

    这公式看着就头疼,不过结果挺有意思。

    中国广东
    回复
  • 暮光法师
    暮光法师 游客

    看不懂,吃个瓜。

    中国河北
    回复
  • Cipher密码
    Cipher密码 读者

    r=2的时候概率这么高?有点超出直觉了。

    印度
    回复
  • 虚无漫游者
    虚无漫游者 读者

    用log确实聪明,之前直接算阶乘内存直接炸了。

    中国北京
    回复
  • SkyPilgrim
    SkyPilgrim 游客

    代码里的变量名太抽象了,up和dr是啥?

    中国浙江
    回复
  • 天际行者
    天际行者 读者

    不用 log 根本存不下大数,亲测过😂

    日本
    回复
    • 电子隐士
      电子隐士 游客

      直接算阶乘内存爆炸,我上次跑崩三台虚拟机😂

      中国浙江@ 天际行者
      回复