反直觉的三门问题

三门问题又被称为蒙提霍尔问题,是一个很反直觉的问题,出自美国的一个电视游戏节目。

题目非常简单:参赛者面前有三扇门,其中一扇门后面有一辆小汽车,另外两扇门后面都是山羊,如果参赛者选中有汽车的那扇门,就可以把汽车开回家。

image.png

当参赛者选择了其中一扇门后,此时主持人打开剩余两扇门其中的一扇,里面是一只山羊,那么现在主持人给参赛者一次重新选择的机会,参赛者应不应该换门去选择另外一扇门?

image.png

我初次看这个问题时觉得当主持人打开一扇门后,那么小汽车在剩余两个门内的概率必然都是 50%,那么换不换门其实意义不大,因为概率都一样,但真的是这样吗?

正确答案却是非常反直觉的,如果参赛者坚持原来的选择,那么选中小汽车的概率为 1/3,如果换门的话,选中小汽车的概率为 2/3。

直观分析

首先我们要明确一点,主持人是知道小汽车在哪个门后面的,这个是解题的前提,否则下面的分析毫无意义。

下面我们来分析一下:当参赛者第一次选择时,任何一扇门有小汽车的概率都是 1/3,所以参赛者所选门后面有小汽车的概率是 1/3,参赛者未选择的两扇门后面有小汽车的概率为 2/3。

image.png

当主持人打开剩余两扇门其中的一扇有山羊的门,那 2/3 的概率就转移到了剩余两扇门中未被打开的那扇门中,而此刻参赛者最初选择的门仍然只有 1/3 的概率选中小汽车,所以说此时换门是最佳的选择。

image.png

图示法

如果上述直观的分析过程不太好理解的话,那么我们通过画图的方式,可以很直观的看到每种选择的概率。

假设三个门分别为A,B,C,参赛者选择了A门,如图所示

image.png

可以很很清楚的看到

如果不换门,选中的概率为 1/3 * 1/2 + 1/3 * 1/2 + 0 + 0 = 1/3

如果换门,选中的概率为 0 + 0 + 1/3 * 1+ 1/3 * 1 = 2/3

极端假设

如果此时你还是不理解的话,我们可以做个极端的假设。

假如有一万扇门,9999 扇门背后都是羊,只有一扇门背后是小汽车。在你选择了一扇门后,此时主持人打开剩余的 9999 扇门中的 9998 扇门,并且背后都是羊,那么此时让你重新选择,你换不换门,我相信此时大多数人哪怕凭直觉也会觉得,换门后选中小汽车的概率更大。

排除法

还有个思路,你可以理解三个答案中只有一个是正确答案,你随机选择了一个,然后主持人在剩余的两个答案中排除掉了错误的一个,这个时候给你一次重新选择的机会你确定不换吗?

用数据说话

实践是检验真理的唯一标准,我写了个简单的程序,对这个游戏模拟了 100 万次。

import random

# 模拟测试的次数
simulationCount = 1000000
# 第一次选中小汽车的次数
firstSelectedSuccessSum = 0
# 第二次重新选择选中小汽车的次数
secondSelectedSuccessSum = 0
for num in range(simulationCount):
    # 初始化所有门
    doors = list(range(1,4))
    # 随机生成小汽车的门位置
    carDoor = random.randint(1,3)
    # 参赛者随机选中一个
    firstSelectedDoor = random.randint(1,3)
    # 主持人在剩下的两个里面随机选择一个
    doors.remove(firstSelectedDoor)
    presenterSelectedDoor = doors[random.randint(0,1)]
    # 主持人选择后剩下的一个门,也就是选手第二次选择的门
    doors.remove(presenterSelectedDoor)
    secondSelectedDoor = doors[0]
    # 因为主持人不能选择有小汽车的门
    # 所以如果上面主持人随机选择的是有小汽车的门,则应该重新选择另一个门
    if carDoor == presenterSelectedDoor:
        secondSelectedDoor = presenterSelectedDoor
    # 如果第一次选中有小汽车的门,累计计数
    if carDoor == firstSelectedDoor:
        firstSelectedSuccessSum = firstSelectedSuccessSum + 1
    # 如果第二次重新选择选中有小汽车的门,累计计数
    elif carDoor == secondSelectedDoor:
        secondSelectedSuccessSum = secondSelectedSuccessSum + 1
# 输出测试结果
print ('模拟测试 %s 次'%simulationCount)
print ('不换门选中小汽车的次数为 {} 次,概率为:{:.2%}'.format(firstSelectedSuccessSum, firstSelectedSuccessSum/simulationCount))
print ('换门后选中小汽车的次数为 {} 次,概率为:{:.2%}'.format(secondSelectedSuccessSum, secondSelectedSuccessSum/simulationCount))

执行结果为

模拟测试 1000000 次
不换门选中小汽车的次数为 333398 次,概率为:33.34%
换门后选中小汽车的次数为 666602 次,概率为:66.66%

结果显而易见,和上述分析的结果一样,坚持最初的选择,选中小汽车概率 1/3,换门后选中小汽车概率 2/3。

如果主持人是随机选的门呢

上面已经说过,主持人是知道小汽车在哪个门后面的,所以主持人可以保证自己打开的一定是后面有山羊的门。

那么肯定有人会问,如果主持人不知道小汽车在哪个门后面,随便选了一个,并且恰好选择了有羊的门,那么此时参赛者换门和不换门选中小汽车的概率各有多大?

这种情况就要分两个维度来看了

维度一:如果从主持人已经打开了一扇有羊的门这个既定事件往后看,那么此时换门和不换门选中小汽车的概率均为 50%。

维度二:如果从主持人打开门之前看,那么换门和不换门选中小汽车的概率均为 1/3,因为还有三分之一的概率是主持人打开了有小汽车的门。

总结

三门问题看似有点违背常理,但只要经过认真思考后,其实也不难理解。

因为最后参赛者重新选门的事件是受前面主持人开门事件所影响的,正是因为主持人是知道小汽车在哪个门后面的,所以主持人在打开门的时候,会刻意避开有小汽车的门,也就造成了后面换门和不换门选择小汽车的概率不均等。明白了这一点,我相信你对换门后选中小汽车的概率为 2/3 也就不会有异议了。