100囚犯问题验证代码结果不符,求错误排查与优化方案
100囚犯问题代码错误分析与修正
错误点梳理
- 箱子生成逻辑错误:原代码用
random.sample(prisoners, 1)循环生成箱子内容,会导致多个箱子出现重复号码,不符合问题中“每个箱子号码是1-100唯一排列”的设定。 - 囚犯寻号逻辑错误:囚犯没有从自己编号对应的箱子开始查找,且编号映射混乱(箱子键为0-99,囚犯编号为1-100,起始位置与跳转逻辑不匹配)。
- 统计逻辑完全偏离:你要验证的是集体获救概率(所有囚犯都成功的实验占比),这一概率约30%;但原代码统计的是每次实验中成功囚犯的平均数量,两者不是同一概念。
- 不良编程习惯:在循环内部重复定义函数,无意义且影响性能。
修正后的代码
import random from statistics import mean def generate_boxes(): # 生成1-100的随机排列,作为每个箱子(编号1-100)内的号码 numbers = random.sample(range(1, 101), 100) # 箱子编号对应1-100,值为内部的囚犯号码 return {i+1: numbers[i] for i in range(100)} def run_single_experiment(): boxes = generate_boxes() all_saved = True for prisoner_id in range(1, 101): current_box = prisoner_id found = False for _ in range(50): if boxes[current_box] == prisoner_id: found = True break # 跳转到当前箱子内号码对应的箱子 current_box = boxes[current_box] if not found: all_saved = False break # 集体获救返回1,否则返回0 return 1 if all_saved else 0 # 运行1000次实验 experiment_results = [run_single_experiment() for _ in range(1000)] # 计算集体获救比例 success_rate = mean(experiment_results) * 100 print(f"集体获救比例:{success_rate:.2f}%")
修正说明
- 箱子生成:用
random.sample(range(1,101),100)直接生成1-100的无重复排列,确保每个箱子号码唯一。 - 寻号逻辑:每个囚犯从自己编号对应的箱子开始,按“当前箱子号码→对应箱子”的规则跳转,完全符合问题中的最优策略。
- 统计逻辑:每次实验仅记录是否所有囚犯都成功,最终计算成功实验占总实验的比例,这才是原问题中约30%的验证目标。
- 代码结构:将功能封装到循环外的函数中,逻辑清晰且性能更优。
内容的提问来源于stack exchange,提问作者code_noah
相关产品推荐
相关产品推荐

