首页 > 解决方案 > python 3中生日悖论的蒙特卡罗模拟

问题描述

生日悖论是每个人在任何给定的 365 天生日的概率都是相等的。我们开始在房间中添加人员。2 个人在同一天过生日的概率是房间里人数的函数?我写的代码如下:

import numpy as np
import matplotlib.pyplot as plt

x=[0]
y=[0]
for j in range(1000):
    if j!=0:
        freq = []
        L1 = list(np.random.randint(low = 1, high=366, size = j))
        result = list((i, L1.count(i)) for i in L1)
        for a_tuple in result:
            freq.append(a_tuple[1])
            print(freq)
        rep = j - freq.count(1)
        prob = rep/j
        y = y + [prob]
        x = x + [j]
print(prob)
plt.plot(x,y)

在这里, L1 = list(np.random.randint(low = 1, high=366, size = j))我选择某人过生日的那一天,并result = list((i, L1.count(i)) for i in L1)计算每天生日的频率。整个事情都是循环的,以解释越来越多的人。

在下面的 for 循环中,我隔离了唯一事件并找到重复并将值存储在 rep 中。接下来,我将概率计算为共享生日的人的比例,并将它们绘制为数字的函数。然而,这个问题需要我找出只有一个共同生日的概率。我该如何计算?我想我必须循环这整个事情来进行多次试验,但这只是提供了一个准确的解决方案,同一程序的变化更少。目前,我认为我的程序提供了共享生日的一小部分人。

生日问题维基百科以获得更好的参考

标签: pythonmontecarlobirthday-paradox

解决方案


笔记

我假设当n人们进入房间时,他们都被赶出房间,然后n+1人们进入房间。

=========================================

我会这样想;

首先,设置probs = [0]*365. 现在,假设有 2 个人进入房间 - 然后我们将他们的生日写在一张纸上并检查这两个日期是否相等。如果它们是,我们增加probs[2]1(是的,有一些我们不需要的索引,Python 是 0 索引等,但为了保持简单)。

现在对 3 个人、4 个人、5 个人做同样的事情......一直到 365。你的数组可能看起来像probs==[0,0,0,0,0,1,0,1,1,0,1,1,1,1,0,1....].

您现在可以从 2 个人重新开始(仍然保持与以前相同的数组,即不要用 0 创建一个新数组!),然后是 3 个人等,并重新开始 1000 次以上。你的数组可能看起来像

probs==[0,0,2,0,4,1,5,2,9,12,10,17....,967,998]

如果将该数组除以 1000(按元素),您现在将模拟概率作为n人的函数。

import numpy as np
import matplotlib.pyplot as plt

N_TOTAL_PERS= 366
N_SIM = 10000 #number of simulations
counts = np.zeros(N_TOTAL_PERS)

for _ in range(N_SIM): 
    for n in range(2,N_TOTAL_PERS):
        b_days = np.random.randint(1,366,size=n) #Get each persons birth-day
        counts [n] += len(b_days) != len(set(b_days)) #Increment if some birthdays are equal    


total_probs = counts/N_SIM #convert to probabilities
total_probs[70] #Get the probability when 70 persons are together (0.9988)
plt.plot(range(N_TOTAL_PERS),total_probs)

它生成一个看起来像 在此处输入图像描述


推荐阅读