囚犯问题Python模拟代码结果与理论值不符,请求排查原因
囚犯问题Python模拟代码结果与理论值不符,请求排查原因
嘿,我仔细看了你的代码和问题描述,发现你的模拟逻辑里有好几处关键错误,这就是为什么结果和理论的33%成功率差这么多的原因。咱们一步步来梳理:
代码里的核心错误点:
- 囚犯循环漏了第100个:你用了
for p_num in range(1, 100),这个循环只会遍历1到99号囚犯,直接漏掉了最后一个囚犯!正确应该用range(1, 101)才能覆盖所有100个囚犯。 - 每个囚犯的起始状态没重置:
temp_p_num这个变量在每个囚犯开始模拟的时候,没有重置为当前囚犯的编号。比如第2个囚犯开始时,temp_p_num还是第1个囚犯最后查到的编号,这完全不符合问题里每个囚犯独立从自己编号开始找的规则。 - 查找逻辑混乱:每个囚犯最多只能打开50个盒子,但你的代码里让查找次数到了99次,而且判断条件完全搞反了——正确的逻辑是:囚犯从自己编号对应的盒子开始,每次根据盒子里的编号去开下一个盒子,最多开50次,找到自己的编号就算成功。你现在的条件判断和变量跳转逻辑完全偏离了这个规则。
- 冗余的循环变量操作:你在
for p_num in range(1, 100)循环里又手动写了p_num +=1,这会导致囚犯的遍历跳过很多,因为for循环本身已经会自动递增p_num了,手动加1会让循环顺序彻底乱掉。
修正后的代码
我把你的代码重新调整了,修正了所有逻辑错误,运行这个版本的话,成功率应该会接近理论上的33%:
import random from random import sample def GenerateBoxes(): # 生成1-100的随机排列,作为盒子里的编号 random_values = sample(range(1, 101), 100) boxes = {i: value for i, value in enumerate(random_values, start=1)} return boxes def SimulateExperiment(timesGiven): success_count = 0 for _ in range(timesGiven): boxes = GenerateBoxes() all_escaped = True # 遍历所有100个囚犯 for prisoner in range(1, 101): current_box = prisoner found = False # 每个囚犯最多开50次盒子 for _ in range(50): if boxes[current_box] == prisoner: found = True break current_box = boxes[current_box] # 只要有一个囚犯没找到,集体无法逃脱 if not found: all_escaped = False break if all_escaped: success_count += 1 return success_count times = 10000 success_count = SimulateExperiment(times) success_percent = (success_count / times) * 100 print(f"成功率: {success_count} out of {times}: {success_percent:.2f}%")
修正后的逻辑说明
- 每个囚犯的查找流程完全独立:每个囚犯开始时都从自己编号的盒子起步,严格按照“盒子里的编号→下一个盒子”的规则跳转,最多尝试50次。
- 正确处理集体逃脱的条件:只要有一个囚犯在50次内没找到自己的编号,整个集体就失败,只有所有囚犯都成功找到,才算逃脱。
- 去掉了冗余的循环操作,逻辑更清晰,避免了原代码里的循环变量冲突问题。
运行这个修正后的代码,模拟10000次以上的话,成功率会稳定在30%-35%之间,和理论值一致。
备注:内容来源于stack exchange,提问作者TJBHobbys
相关产品推荐
相关产品推荐

