我正在为我的统计类做这个生日问题,它需要检查任何人拥有相同生日的概率。对于23个人,我应该得到0.5的概率。我做了一万次试验,但我的概率是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)发布于 2020-09-11 20:02:53
你一直在计算重叠的生日,即使你已经找到了一个用于试验的生日。
发布于 2020-09-11 20:01:57
你遇到的问题是,在每个实验中,在找到一对生日相同的人之后,你可以继续下去,并且可以为每一对额外的人数一次。您确实希望从内部循环执行break,但因为它涉及跳出两层循环,这在break中很难实现,因此从函数执行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.5072972343239857Addendum -在评论中讨论过之后,你似乎想看看如何通过break跳出嵌套循环的例子。答案是,当您从内部循环中断时,需要设置一个标志,您可以对其进行测试,以决定是否也从外部循环中断。就像这样(为了简洁,再次使用for循环,但同样也适用于原始的while循环)……
import random
import numpy as np
n = 10000
m = 23
a = np.random.randint(1,365, size=(n,m))
count = 0
for j in range(n):
match = False
for i in range(m):
for k in range(i+1, m):
if a[j][i] == a[j][k]:
count += 1
match = True
break
if match:
break
z = count / n
print("Probability = ", z)同样,这应该报告的概率接近0.5。
https://stackoverflow.com/questions/63846470
复制相似问题