Python Code for Computing Generalized Birthday Problem

专业相关2026年3月20日发布 芮和
316 320

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).

© 版权声明

相关文章

32 条评论

  • 尘梦
    尘梦 读者

    对数防溢出,写代码时这招挺常用

    法国
    回复
    • 众声喧哗
      众声喧哗 读者

      确实,防溢出必备

      美国@ 尘梦
      回复
  • 微风细雨
    微风细雨 读者

    直接用对数处理大数,这法子挺巧的

    中国广东
    回复
    • 云隐清风
      云隐清风 读者

      确实,避免溢出的好办法

      中国台湾@ 微风细雨
      回复
  • 布丁云
    布丁云 读者

    对数方法防溢出挺实用的

    中国山东
    回复
  • 小雪球
    小雪球 读者

    代码排版可以再优化下

    中国福建
    回复
    • Bella贝拉
      Bella贝拉 读者

      同感,看着有点乱

      中国北京@ 小雪球
      回复
  • 量子迷雾
    量子迷雾 读者

    对数变换这思路不错

    印度
    回复
  • 京剧情深
    京剧情深 读者

    算得挺快,结果一目了然

    中国江苏
    回复
  • 幻夜琉璃
    幻夜琉璃 读者

    这个公式推导过程能展开讲讲吗?

    中国江苏
    回复
  • 霜降寒夜
    霜降寒夜 读者

    对数计算这块写得蛮清楚

    中国上海
    回复
    • 星空下的梦
      星空下的梦 读者

      对,用对数处理确实清晰

      美国@ 霜降寒夜
      回复
  • 烽火使
    烽火使 读者

    概率论作业刚好用上了,帮大忙了!

    英国
    回复
  • 银月法师
    银月法师 读者

    对数处理防溢出这招挺实用

    巴基斯坦
    回复
    • 白绫吊死鬼
      白绫吊死鬼 读者

      确实,处理大数时常用这招

      美国@ 银月法师
      回复
  • 懒人日记本
    懒人日记本 读者

    M1芯片上试了,跑得飞快,没问题。

    马来西亚
    回复
  • 动如脱兔的你
    动如脱兔的你 游客

    这结果说明生活中很多“巧合”其实概率挺高的?

    日本
    回复
  • 晨曦笔记
    晨曦笔记 游客

    完全看不懂,就当看个热闹吧。

    马来西亚
    回复
  • LunarLullaby
    LunarLullaby 读者

    之前写作业也卡在这题,用对数转换是标准解法了。

    韩国
    回复
  • 灵异侦探
    灵异侦探 游客

    变量名起得也太随意了,up和dr完全猜不出意思。

    中国湖北
    回复
  • 弯酸
    弯酸 游客

    这代码跑起来快吗?会不会有性能瓶颈?

    中国山东
    回复
  • 月影谣
    月影谣 游客

    r=2的概率高得有点吓人,现实里真这么准?

    中国上海
    回复
  • 跳跃的小鸡
    跳跃的小鸡 读者

    用log算阶乘确实巧妙,避免了溢出问题。

    新西兰
    回复
  • 星旅者
    星旅者 游客

    range边界确实容易写错,debug了好几次。

    中国广东
    回复
  • 星爵彼得
    星爵彼得 游客

    之前也卡在阶乘计算上,加个log确实管用

    孟加拉
    回复
  • 胡杨林间
    胡杨林间 读者

    r=2时50人概率接近1?这也太吓人了

    中国青海
    回复
  • 诚实的镜子
    诚实的镜子 游客

    GitHub链接啥时候公开?想跑跑看

    日本
    回复
  • GoldenGaze
    GoldenGaze 游客

    23个人就过半概率?比想象中少多了

    中国江苏
    回复
  • 小猪猪猪
    小猪猪猪 读者

    吃个瓜,数学渣表示完全看不懂🍉

    中国江苏
    回复
  • DewStrider
    DewStrider 游客

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

    中国江苏
    回复
  • 幽冥烛阴
    幽冥烛阴 读者

    用log确实稳,之前算阶乘内存炸过好几次

    中国广东
    回复
  • 玄影梦
    玄影梦 游客

    这公式看着头大,不过代码实现倒是挺巧妙的😂

    中国江苏
    回复