我死守不换门输了一万次:蒙提霍尔实测胜率差出一倍
我遇到的现场
事情起于一次团队内部的小赌局。周末线上团建,有人搬出了蒙提霍尔问题:三扇门,一扇后面是车,两扇后面是羊,你选一扇,主持人开一扇有羊的门,问你要不要换。我说不换,理由听起来很硬——主持人开门之后只剩两扇门,概率各一半,换不换无所谓。同组的算法工程师当场笑了,说换门胜率是三分之二。我们吵了半小时,谁也没说服谁。
吵到最后他说了一句让我印象深刻的话:“你别跟我讲直觉,你跑一万次模拟,数据会替你说话。”我当时其实是有点不服气的,因为按我的推理,两扇门对称、信息对等,凭什么一个 66% 一个 33%?但我也清楚,这种纯概率的争论靠嘴是吵不出结果的,必须写代码验证。而且我不敢只跑几百次就下结论——样本小了,波动完全可能把结论带偏,到时候反而给对方递刀。
还原实验怎么设
回家后我写了一段 Python 模拟,逻辑上把一轮游戏完整拆开:随机放车、随机选门、主持人只开有羊的门、最后判定胜负。为了让结果可复现,我固定了随机种子 random.seed(42),每组设置跑 10000 轮。代码不长,核心是这一个函数:
import random
random.seed(42)
N = 10000 # rounds per setup
def play(d, switch):
# one full round: car placement, player pick, host reveal, outcome
car = random.randrange(d)
pick = random.randrange(d)
if not switch:
return pick == car
if pick == car:
return False # host reveals d-2 goats, switching loses
others = [x for x in range(d) if x != pick]
goats = [x for x in others if x != car]
opened = random.sample(goats, d - 2) # host only opens goat doors
remain = [x for x in others if x not in opened]
return car in remain
这里有一个实现上的小设计:死守和换门我没有分别去数赢的次数,而是用 st = N - sw 直接取补集。因为在一轮游戏里,换门赢和死守赢是严格互斥且互补的事件,赢了换门就等于输了死守,这样写既省一半计算,也从根上杜绝了两个口径统计不一致的可能。另外我把门的数量做成参数 d,除了经典的 3 门,还测了 4 门和 10 门——我想看看门越多,换门的优势到底是被放大还是被稀释。
跑出来的数据
脚本一次跑完三种门数的对比,输出是这样的:

3 门场景:死守赢了 3400 次,胜率 34.0%;换门赢了 6600 次,胜率 66.0%,和理论值 66.7% 只差 0.7 个百分点。4 门场景差距进一步拉开:死守 24.9% 对换门 75.1%,理论值 75.0% 几乎严丝合缝。最扎眼的是 10 门:死守只剩 1019 次、10.2%,换门 8981 次、89.8%,理论值 90.0%。也就是说门数从 3 涨到 10,换门对死守的优势从大约 2 倍一路放大到接近 9 倍。
输出末尾还有两行连击数据:3 门下,永远换门的最长连胜是 25 轮,永远死守的最长连胜只有 8 轮。25 比 8,这个差距比胜率本身更直观——如果真拿一万块钱连续下注,死守派连赢 8 把之后大概率已经开始怀疑人生了。
我原来想错在哪
翻车点找到了:我犯的错误是把“主持人开门”当成了一条中性信息。直觉上,三扇门剩两扇,各 1/2,这是把开局选择和主持人行为混为一谈了。事实是,我的第一次选择只有 1/3 概率命中车,剩下 2/3 的概率都压在另外那组门上。主持人开门这个动作不是随机的——他明确知道车在哪,并且只开羊门,这个约束把那 2/3 的概率全部浓缩到了最后一扇没开的门上。
用数据反推就很清楚:死守的胜率永远等于我第一次蒙对的概率,3 门就是 1/3,10 门就是 1/10,模拟结果 34.0% 和 10.2% 都在这个锚点附近小幅波动。而换门的胜率恒等于 (d-1)/d,也就是把“第一次没蒙对”的全部可能性兑现。10 门时死守 10.2% 对换门 89.8%,差的不是运气,是我从一开始就把 90% 的胜率拱手让了出去。这次实验也有局限:10000 轮在 3 门场景下 34.0% 与理论 1/3 仍有偏差,种子固定后换个 seed 结果会小幅漂移;而且主持人行为是照规则写的“标准主持人”,如果现实里主持人会耍手段(比如只在你猜对时才提议换门),整套结论就不成立。
下次怎么绕开
这次实验给我留下了一条可执行的习惯:凡是两个方案谁也说服不了谁,别在会议室里辩论,花十分钟写个模拟器,把参数固定、轮次跑到一万以上,让补集统计替双方闭嘴。直觉在条件概率面前几乎从不靠谱,尤其是那种“看起来对称”的场景——对称的只是门的数量,不是信息。
还有一个反直觉的收获值得单独记下:门越多,死守的代价越惨烈。3 门时错信直觉只亏一倍,10 门时直接亏 9 倍。所以下次再遇到“多个选项二选一”的类似局面,先别急着五五开,问一句:有没有一个“知道内情的主持人”在替我筛掉部分选项?如果有,那个被筛剩的选项,含金量远比我以为的高。你要是不信,把上面的代码跑一遍,换个种子也行——数字不会陪任何人演。