
本文详解 monty hall 问题的正确模拟方法,指出原始代码中“提前判定胜利”的致命逻辑错误,并提供可复用、结构清晰的 python 实现,验证切换策略胜率约 66.7%,不切换约 33.3%。
本文详解 monty hall 问题的正确模拟方法,指出原始代码中“提前判定胜利”的致命逻辑错误,并提供可复用、结构清晰的 python 实现,验证切换策略胜率约 66.7%,不切换约 33.3%。
Monty Hall 问题的核心在于信息揭示的时序性与条件依赖性:参赛者先随机选一门(此时胜率 1/3),主持人随后必然打开一扇未选且无奖的门(此动作不随机,而是基于真实奖品位置和初始选择的确定性操作),最后参赛者决定是否切换。任何模拟若忽略这一因果链条,就会得出错误结论。
原始代码中的关键错误在于以下两行:
if chosenDoor == correct:
wins += 1
continue这段逻辑在主持人开门前就提前统计了一次“不换即赢”的情况,而后续又对“换门后是否赢”再次判断——导致每局至少被计为一次胜利(要么初始就对,要么换后才对),最终胜率趋近 100%。这完全违背了问题设定:现实中,玩家只能在主持人开门后做一次最终选择,不存在“先判初选再判换选”的双重计分机制。
正确的模拟应严格遵循三步时序:
立即学习“Python免费学习笔记(深入)”;
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
- 随机设定奖品门(
correct)与初始选择门(chosenDoor); - 主持人依据规则打开一扇既非
chosenDoor也非correct的门(openedDoor); - 根据策略(换或不换)确定最终选择门,仅在此刻判断胜负。
以下是重构后的健壮实现,封装为函数并支持策略对比:
import random
def get_other_door(num1, num2):
"""返回 1-3 中既不等于 num1 也不等于 num2 的唯一整数"""
for door in range(1, 4):
if door != num1 and door != num2:
return door
def monty_hall_simulate(switch: bool, trials: int = 9000) -> float:
"""
模拟 Monty Hall 问题
Args:
switch: 是否在主持人开门后切换选择
trials: 模拟总轮数
Returns:
胜率(浮点数)
"""
wins = 0
for _ in range(trials):
correct = random.randint(1, 3)
chosen = random.randint(1, 3)
# 主持人开门:必须是非选非奖之门
# 注意:即使 chosen == correct,主持人仍有两个空门可选,任选其一即可
remaining_doors = [d for d in range(1, 4) if d != chosen]
if chosen == correct:
# 初始选中,主持人随机开剩下两扇空门之一
opened = random.choice(remaining_doors)
else:
# 初始未中,主持人只能开唯一剩下的空门
opened = next(d for d in remaining_doors if d != correct)
# 执行策略
if switch:
# 切换到剩下未开未选的那扇门
chosen = next(d for d in range(1, 4) if d != chosen and d != opened)
# 仅在此刻判定最终结果
if chosen == correct:
wins += 1
return wins / trials
# 运行对比实验
print(f"切换策略胜率: {monty_hall_simulate(switch=True):.3f}") # ≈ 0.667
print(f"不切换策略胜率: {monty_hall_simulate(switch=False):.3f}") # ≈ 0.333关键改进说明:
- ✅ 移除提前胜利判定:胜负只在最终选择后计算一次;
- ✅ 主持人逻辑更严谨:显式处理
chosen == correct时的随机开门情形(虽不影响理论概率,但更贴近现实); - ✅ 函数化与参数化:支持灵活配置策略与试验次数,便于批量验证;
- ✅ 返回胜率而非绝对值:直接输出概率,语义更清晰。
注意事项:
-
get_other_door函数在输入相同时行为未定义,但本模拟中chosen与correct可能相同,而opened总与二者不同,故调用安全; - 理论上,切换胜率恒为 2/3,不切换恒为 1/3;实际模拟因随机性会有小幅波动(如 9000 次试验下 ±1% 属正常范围);
- 若需更高精度,可增大
trials或运行多次取均值。
通过严格还原问题的决策时序与约束条件,该模拟不仅修复了原始 bug,更成为理解条件概率与反直觉推理的有力教学工具。

















