嵌套循环问题

时间:2020-09-11 11:47:45

标签: python loops

我正在为我的统计课处理这个生日问题,这需要检查任何人共享同一生日的可能性。对于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)

2 个答案:

答案 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。