别再被直觉骗了!用Python模拟10000次,带你彻底搞懂三门问题(蒙提霍尔悖论)

张开发
2026/6/9 14:55:54 15 分钟阅读
别再被直觉骗了!用Python模拟10000次,带你彻底搞懂三门问题(蒙提霍尔悖论)
用Python暴力模拟10000次为什么直觉在三门问题中总是错的第一次听说三门问题时我和大多数人一样坚信换不换门概率都一样。直到亲手用代码模拟了上万次游戏过程那些冰冷的数字才彻底击碎了我的直觉认知。这大概就是程序员独有的浪漫——当逻辑和直觉打架时让计算机用海量实验告诉我们真相。1. 反直觉的概率陷阱想象你参加一档真人秀节目面前有三扇关闭的门门A、门B和门C。主持人告诉你其中一扇门后是辆跑车另外两扇门后是山羊。你选择了门A后主持人他知道每扇门后有什么打开了门C展示一只山羊然后问你要不要换成门B大多数人会这样思考现在剩下两扇门A和B跑车在任意一扇门后的概率应该是50%对50%所以换不换无所谓这个推理听起来完全合理但却是完全错误的。让我们用Python模拟来揭示其中的概率把戏。关键提示主持人的行为不是随机的——他一定会打开一扇有山羊的门这个动作传递了额外信息。2. 构建模拟实验我们将用Python模拟这个游戏10000次分别统计坚持初始选择和更换选择的胜率。以下是完整的实验代码import random from collections import defaultdict def monty_hall_simulation(trials10_000): results defaultdict(int) for _ in range(trials): # 随机放置汽车0,1,2分别代表三扇门 car_position random.randint(0, 2) # 玩家初始选择 first_choice random.randint(0, 2) # 主持人打开一扇有山羊的门 opened_door next( door for door in range(3) if door ! first_choice and door ! car_position ) # 玩家决定是否换门 switch_choice next( door for door in range(3) if door ! first_choice and door ! opened_door ) # 记录结果 if first_choice car_position: results[stay_win] 1 if switch_choice car_position: results[switch_win] 1 return results运行这个函数你会得到类似这样的输出{ stay_win: 3325, # 坚持选择的获胜次数 switch_win: 6675 # 更换选择的获胜次数 }3. 实验结果分析让我们把多次模拟结果整理成对比表格策略获胜次数胜率坚持初始选择3,32533.25%更换选择6,67566.75%这个结果可能让你大吃一惊——更换选择后的胜率几乎是坚持选择的两倍为什么会出现这种情况概率重新分配的关键点初始选择时每扇门有1/3的概率主持人打开一扇门后他没有给你的初始选择带来新信息但他打开门的行为把另外两扇门你未选的的总概率2/3集中到了剩下的那扇门上4. 可视化概率变化为了更直观理解让我们用ASCII图表展示概率流动过程初始概率分布 --------------------- | 1/3 | 1/3 | 1/3 | | 门A | 门B | 门C | --------------------- 假设你选择门A主持人打开门C山羊 概率重新分配 --------------------- | 1/3 | 2/3 | 0 | | 门A | 门B | (已开)| ---------------------这个可视化说明了一个关键洞见主持人的行为本质上是帮你排除了一个错误选项把另外两扇门的概率优势集中到了剩下的那扇门上。5. 极端案例验证如果还是难以接受考虑一个极端版本——有100扇门你随机选择一扇门胜率1%主持人打开98扇门留下你的选择和另一扇门现在你会坚持1%胜率的选择还是切换到那扇被精心保留的门在这个极端案例中直觉会明显倾向于应该换门因为主持人用他的行为把99%的概率集中到了那扇门上。三门问题只是这个逻辑的迷你版本。6. 常见误区解析在与数百名开发者讨论这个问题后我总结了最常见的几种认知偏差误区一独立事件假设错误认为主持人开门后剩下两门概率应该重新计算实际上主持人行为与你的初始选择相关不是独立事件误区二忽略信息价值低估了主持人知道门后情况这一信息如果主持人随机开门可能开到汽车情况就完全不同误区三小样本错觉用少量试验如玩3次来判断概率概率规律需要大样本才能显现7. 进阶思考代码优化与扩展我们的基础模拟已经证明了结论但还可以做更多有趣探索优化1动态可视化import matplotlib.pyplot as plt def plot_probability_trend(max_trials10_000): stay_probs, switch_probs [], [] for n in range(1, max_trials1): results monty_hall_simulation(1) stay_probs.append(sum(stay_probs[-1:]) results[stay_win] / n) switch_probs.append(sum(switch_probs[-1:]) results[switch_win] / n) plt.plot(stay_probs, label坚持选择) plt.plot(switch_probs, label更换选择) plt.axhline(y1/3, colorr, linestyle--) plt.axhline(y2/3, colorg, linestyle--) plt.legend() plt.show()这段代码会绘制胜率随试验次数变化的曲线直观展示大数定律如何使概率收敛到理论值。扩展1多门多奖品版本def extended_monty_hall(doors3, prizes1, trials10_000): results {stay:0, switch:0} for _ in range(trials): # 随机放置奖品 positions random.sample(range(doors), prizes) # 玩家初始选择 choice random.randint(0, doors-1) # 主持人打开门确保不暴露奖品 opened [d for d in range(doors) if d ! choice and d not in positions] opened random.sample(opened, doors-prizes-1) # 切换选择 switch [d for d in range(doors) if d ! choice and d not in opened] switch random.choice(switch) # 统计结果 if choice in positions: results[stay] 1 if switch in positions: results[switch] 1 return results这个扩展版本可以模拟更多门和奖品的情况比如5扇门2辆汽车10扇门3辆汽车运行结果会展示不同配置下的最优策略变化。8. 为什么这个悖论如此著名三门问题之所以成为经典是因为它完美展示了人类认知的几个脆弱点概率直觉的局限性我们进化出的直觉适合处理简单确定的情况对复杂概率容易误判信息价值的误估难以意识到主持人行为中包含的关键信息确认偏误一旦形成初始判断如概率应该均等就会寻找支持这个判断的证据在数据分析项目中我多次遇到类似情况——团队成员对某些统计结果表示怀疑因为不符合直觉。这时候最好的解决方法就是像我们这里做的一样用代码和实验说话。

更多文章