我正在为我的统计课处理这个生日问题,这需要检查任何人共享同一生日的可能性。对于23个人,我应该获得0.5的概率。我做了1万次试用,但我的机率是0.7。它必须是我冗长地检查和调试的代码。
import random
import numpy as np
n=10_000
m=23
a= np.random.randint(1,365, size=(n,m))
b=[]
count=1
j=0
while j<n:
i=0
while i<m:
k=i+1
while k<m:
if a[j][i]==a[j][k]:
b.append(count)
k+=1
i+=1
j+=1
z=(len(b)/n)
print("Probability = ",z)
答案 0 :(得分:1)
即使您已经找到一个要进行试验的生日,您仍在计算重叠的生日。
答案 1 :(得分:0)
您遇到的问题是,在每个实验中,找到一对拥有相同生日的配对后,您可以继续进行下去,并且可以为每个额外的配对计算一个。您确实想从内部循环中break
,但是由于它涉及跳出两个级别的循环(使用break
不容易实现),因此{{1} }代替。
还可以通过将return
循环替换为while
循环并仅使用整数计数器而不是for
值的列表来进行整理,从而得到以下结果:
1
在一次测试中得到了结果:
import random
import numpy as np
def share_birthday(birthdays):
m = len(birthdays)
for i in range(m):
for k in range(i + 1, m):
if birthdays[i] == birthdays[k]:
return 1
return 0
n = 10000
m = 23
a = np.random.randint(1, 365, size=(n,m))
count = 0
for j in range(n):
if share_birthday(a[j]):
count += 1
z = count / n
print("Probability = ",z)
为了进行比较,这是概率的直接计算(不依赖于蒙特卡洛方法):
Probability = 0.5101
给出:
p = 1.
m = 23
days = 365
for i in range(m):
p *= (days - i) / days
q = 1 - p
print('Probability = ', q)
附录-在评论中进行讨论之后,您似乎想看到一个示例,说明如何Probability = 0.5072972343239857
脱离嵌套循环。答案是,当您从内部循环中断时,您需要设置一个标志,可以对其进行测试以便确定是否也从外部循环中断。像这样(为了简洁起见,再次使用break
循环,但是同样适用于原始的for
循环)...
while
同样,这应该报告概率接近0.5。