代码:
# @Time : 2022/8/9 11:00
# @Author : HJL
# 100 prisoners problem
from random import shuffle
times = 10000 # 试验模拟次数
T = 0 # 试验计次变量
count = times # count用于统计成功次数,先假设全部成功
# (什么?我不能每次成功后次数加1吗?(实际上这样对于成功次数的统计会更简便))
while T < times: # 模拟times次试验
box = [i + 1 for i in range(100)] # 创建100个盒子,分别放入写有该盒子序号的纸条
shuffle(box) # 打乱100个盒子内的纸条
box.insert(0, -1) # 免去下标减1
for i in range(1, 101): # 100个人轮流进入房间
t = 50 # 每个人50次机会
num = i # i赋值给num,i备用
while t > 0: # 50次机会
num = box[num] # 拿num盒子里的纸条并把结果当做下次的num
if num == i: # 如果找到写有自己号的纸条
break # 则囚犯i成功,离开房间
t -= 1 # 可尝试次数减1
else: # 如果50次循环后正常退出,则说明囚犯i失败
count -= 1 # 总成功次数减1
break # 直接结束游戏
T += 1 # 累加
print('{}次试验成功率:{:f}'.format(times, count / times)) # 输出成功率
效果图:
如图所示,在10000次模拟下成功率达到了惊人的31%,这相对于随机拿取的方案( ( 1 2 ) 100 ≈ 0.0000000000000000000000000000008 (\frac{1}{2})^{100} \approx 0.0000000000000000000000000000008 (21)100≈0.0000000000000000000000000000008)成功率提升了30个数量级。