野生技术宅协会

三门问题的Python代码模拟

2018-11-24  本文已影响10人  乐百川

三门问题是一个经典的概率问题,问题复制自百度百科:

参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,选中后面有车的那扇门可赢得该汽车,另外两扇门后面则各藏有一只山羊。当参赛者选定了一扇门,但未去开启它的时候,节目主持人开启剩下两扇门的其中一扇,露出其中一只山羊。主持人其后会问参赛者要不要换另一扇仍然关上的门。问题是:换另一扇门会否增加参赛者赢得汽车的机率?如果严格按照上述的条件,即主持人清楚地知道,自己打开的那扇门后是羊,那么答案是会。不换门的话,赢得汽车的几率是1/3。换门的话,赢得汽车的几率是2/3。

这个问题常见的误区在于以为换不换门概率一样。不过这里有一个假定需要特别注意,就是主持人知道哪扇门后面有奖,哪扇门后面没奖,并会帮助参赛者排除一个错误答案,这样一来答案就比较容易理解了。

当然,为了使问题更明确,人们还更清晰的规定了假设,同样摘自百度百科:

Mueser 和 Granberg 透过厘清细节,以及对主持人的行为加上明确的介定,提出了对这个问题的一种不含糊的陈述 [5]
* 现在有三扇门,只有一扇门有汽车,其余两扇门的都是山羊。
* 汽车事前是等可能地被放置于三扇门的其中一扇后面。
* 参赛者在三扇门中挑选一扇。他在挑选前并不知道任意一扇门后面是什麽。
* 主持人知道每扇门后面有什么。
* 如果参赛者挑了一扇有山羊的门,主持人必须挑另一扇有山羊的门。
* 如果参赛者挑了一扇有汽车的门,主持人等可能地在另外两扇有山羊的门中挑一扇门。
* 参赛者会被问是否保持他的原来选择,还是转而选择剩下的那一扇门.

将问题完全明确化之后,我们就可以用代码来模拟了。Python代码很简单:

# 三门问题代码模拟


def three_door_question(times: int):
    import random
    result_if_not_change = 0
    result_if_change = 0
    for i in range(0, times):
        doors = [1, 2, 3]  # 3是大奖
        random.shuffle(doors)
        first_choice = doors[random.randint(0, 2)]
        doors.remove(first_choice)
        # 如果大奖在剩下的里面,由主持人排除一个错误答案,剩下大奖
        if 3 in doors:
            doors = [3]
        # 如果大奖已经被选了,主持人随机排除剩下一个错误答案
        else:
            doors.remove(random.choice((1, 2)))
        if first_choice == 3:
            result_if_not_change = result_if_not_change + 1
        if doors[0] == 3:
            result_if_change = result_if_change + 1

    print(
        f'Total times:{times}, prob of not change is {result_if_not_change / times}, prob of change is {result_if_change / times}')


three_door_question(10000)
three_door_question(100000)
three_door_question(1000000)

# 运行结果
'''
Total times:10000, prob of not change is 0.329, prob of change is 0.671
Total times:100000, prob of not change is 0.33306, prob of change is 0.66694
Total times:1000000, prob of not change is 0.333483, prob of change is 0.666517
'''

可以看到,随着次数逐渐增加,换门的结果越来越趋向于2/3,确实验证了前面的结论。当然,这个代码写的比较简单,所以性能比较差,有兴趣的同学可以使用其他语言或者方法来实现。

上一篇下一篇

猜你喜欢

热点阅读