📜  门|门 CS 1996 |问题 13(1)

📅  最后修改于: 2023-12-03 15:12:45.871000             🧑  作者: Mango

门|门 CS 1996 |问题 13

这是一个经典的问题,也称为“两枚硬币问题”。问题可以简述如下:

你站在两个门前,一个门通向自由,另一个门通向死亡。你不知道哪个门通向哪里,但知道一扇门后有自由,另一扇门后有死亡。在做出决定前,你可以选一个门。选定之后,主持人会打开另外一扇门,露出其中的一个死亡背后的门,并问你是否要更改你的选择。问题是:你应该更改选择吗?

这个问题的答案可能会让人意外。如果你选择更改选择,你获胜的机会将会增加。为什么会这样呢?让我们来解释一下。

一开始,你有两个选择,每个选择的赢得机会都是50%。但是,假设你选择的门是1号门,那么门后面自由的机会只有50%。也就是说,如果你选择保留选择,你最终获胜的机会只有1/2 * 1/2 + 1/2 * 0 = 1/4。然而,如果你更改选择,你将有50%的机会选择那扇背后有自由的门,这样你赢得机会将会变为1/2 * 1 = 1/2。因此,更改选择将会使你的获胜机会翻倍。

现在你也知道了,在这个问题中更改选择是正确的,但似乎很难理解。如果你不相信,请尝试在代码中自己模拟这个过程!

模拟代码
import random

def simulate_game(change_choice):
    # 三个门,其中一个背后有自由,另外两个背后有死亡
    doors = [0, 0, 0]
    doors[random.randint(0, 2)] = 1
    
    # 玩家的初始选择
    player_choice = random.randint(0, 2)
    
    # 主持人选择一个门揭示一个死亡
    show_door = random.choice([i for i in range(3) if i != player_choice and doors[i] != 1])
    
    # 玩家更改选择
    if change_choice:
        player_choice = [i for i in range(3) if i != player_choice and i != show_door][0]
    
    # 判断胜利或失败
    return doors[player_choice] == 1

# 不更改选择
win_count = sum([simulate_game(False) for _ in range(100000)])
print("不更改选择:", win_count / 100000)

# 更改选择
win_count = sum([simulate_game(True) for _ in range(100000)])
print("更改选择:", win_count / 100000)

输出:

不更改选择: 0.33337
更改选择: 0.66628

如你所见,更改选择的胜利率高得多,这个问题也被称为“蒙提霍尔问题”,是概率论中的一个经典问题,因为它展示了概率不符合直觉的一面。