用Python模拟10000次,我彻底搞懂了那个反直觉的‘三门问题’
·
用Python模拟10000次,我彻底搞懂了那个反直觉的‘三门问题’
第一次听说三门问题时,我和大多数人一样坚信换不换门根本没区别——毕竟剩下两扇门看起来概率都是50%对吧?直到我用Python写了不到20行代码,跑了10000次模拟实验,结果让我彻底服气:换门策略的胜率竟然稳定在66.7%左右,是不换门的两倍!今天我就带大家亲手用代码破解这个概率谜题,你会惊讶于蒙特卡洛模拟的魔力。
1. 三门问题为什么反直觉
想象你参加一个游戏节目,面前有三扇关闭的门:A、B和C。主持人告诉你其中一扇门后是辆豪车,另两扇门后是山羊。你选择了A门,接着主持人(他知道每扇门后有什么)打开了B门展示一只山羊,然后问:"要不要换成C门?"
直觉告诉我们:
- 打开B门后剩下A和C两扇门
- 两扇门似乎概率均等(50% vs 50%)
- 换不换应该没区别
但数学证明和实验数据都显示:坚持原选择(A门)的胜率是1/3,而换到C门的胜率高达2/3。这种反直觉现象源于:
- 初始选择时,选到汽车的概率只有1/3
- 主持人必定会打开一扇有山羊的门
- 如果初始选择是山羊(概率2/3),换门必定获胜
注意:主持人的行为提供了额外信息,改变了条件概率分布,这与纯粹随机打开一扇门有本质区别
2. 构建Python模拟实验
让我们用Python的random模块实现这个实验。完整代码不到20行,却能揭示概率本质:
import random
def simulate_monty_hall(trials):
stay_wins = 0
switch_wins = 0
for _ in range(trials):
# 随机放置汽车(0:山羊, 1:山羊, 2:汽车)
car_position = random.randint(0, 2)
# 玩家初始选择
first_choice = random.randint(0, 2)
# 主持人打开一扇有山羊的门(不能是玩家选择的门)
opened_door = next(i for i in range(3)
if i != first_choice and i != car_position)
# 换门选择
switch_choice = next(i for i in range(3)
if i != first_choice and i != opened_door)
# 统计结果
if first_choice == car_position:
stay_wins += 1
elif switch_choice == car_position:
switch_wins += 1
return stay_wins, switch_wins
关键实现细节:
random.randint(0, 2)模拟随机初始选择- 主持人行为通过列表推导式精确实现
- 换门策略自动排除已打开和初始选择门
3. 实验结果与数据分析
运行10000次模拟,结果令人震撼:
| 策略类型 | 获胜次数 | 胜率 |
|---|---|---|
| 坚持原选择 | 3321次 | 33.21% |
| 换门策略 | 6679次 | 66.79% |
多次实验数据对比:
| 实验批次 | 不换门胜率 | 换门胜率 |
|---|---|---|
| 1 | 33.45% | 66.55% |
| 2 | 33.12% | 66.88% |
| 3 | 33.67% | 66.33% |
发现规律:
- 换门胜率稳定在66.7%附近波动
- 实验次数越多,结果越接近理论值
- 标准差随实验次数增加而减小
用matplotlib可视化结果更直观:
import matplotlib.pyplot as plt
trials = [100, 1000, 5000, 10000]
stay_probs = []
switch_probs = []
for t in trials:
s, w = simulate_monty_hall(t)
stay_probs.append(s/t)
switch_probs.append(w/t)
plt.plot(trials, stay_probs, label='保持选择')
plt.plot(trials, switch_probs, label='换门策略')
plt.axhline(y=0.666, color='r', linestyle='--')
plt.axhline(y=0.333, color='b', linestyle='--')
plt.xlabel('实验次数')
plt.ylabel('胜率')
plt.legend()
plt.show()
4. 为什么直觉会欺骗我们
这个反直觉现象源于几种认知偏差:
- 忽略信息更新:主持人行为提供了额外信息
- 错误概率分配:认为剩余两门概率应该均等
- 锚定效应:过度依赖初始选择的1/3概率印象
用条件概率公式可以精确计算:
- 设初始选择汽车事件为A(P(A)=1/3)
- 换门获胜事件为B(即初始未选汽车,P(B)=2/3)
$$ P(\text{换门胜}) = P(\neg A) = 1 - P(A) = \frac{2}{3} $$
5. 进阶实验与变体验证
为了更深入理解,我们可以修改实验条件:
变体1:主持人随机开门
# 修改主持人行为为随机开门(可能直接开出汽车)
opened_door = random.choice([i for i in range(3)
if i != first_choice])
此时实验结果:
| 策略 | 胜率 |
|---|---|
| 不换 | 50% |
| 换门 | 50% |
关键区别:
- 当主持人必定避开汽车时,提供信息量更大
- 随机开门不提供有效信息,概率回归50/50
变体2:增加门数量 将门数量扩展到100扇,主持人打开98扇山羊门后:
- 不换胜率:1%
- 换门胜率:99%
这个极端案例让概率差异变得显而易见。
更多推荐



所有评论(0)