python - Monty Hall 模拟未按预期工作

标签 python python-3.x simulation python-3.6

我一直在尝试解决 monty hall problem为了提高编码水平,我使用Python,这就是为什么我尝试随机化一切。问题是:我遇到了一些麻烦。你们大多数人可能都知道蒙蒂问题应该表明改变门的胜率(66%)比留在所选门上(33%)更高。由于某些奇怪的原因,尽管我的模拟显示这两种情况的胜率都是 33%,但我不太确定为什么。

代码如下:

from random import *


def doorPriceRandomizer():
    door1 = randint(0,2) #If a door is defined 0, it has a price in it
    door2 = randint(0,2) #If a door is defined either 1 or 2, it has a goat in it.
    door3 = randint(0,2)
    while door2 == door1:
        door2 = randint(0,2)
    while door3 == door2 or door3 == door1:
        door3 = randint(0,2)
    return door1,door2,door3 #This random placement generator seems to be working fine.


while True:
    loopStart = 0
    amountWin = 0
    amountLose = 0
    try:
        loopEnd = int(input("How often would you like to run this simulation: "))
        if loopEnd < 0:
            raise ValueError
        doorChangeUser = int(input("[0] = Do not change door; [1] = Change door: "))
        if doorChangeUser not in range(0,2):
            raise ValueError
    except ValueError:
            print("Invalid input. Try again.\n")
    else:
        while loopStart != loopEnd:
            gameDoors = doorPriceRandomizer()
            inputUser = randint(0,2)
            if doorChangeUser == 0:
                if gameDoors[inputUser] == 0:
                    amountWin += 1
                    loopStart += 1
                else:
                    amountLose += 1
                    loopStart += 1
            elif doorChangeUser == 1:
                ChangeRandom = 0
                while gameDoors[ChangeRandom] == gameDoors[inputUser]:
                    ChangeRandom = randint(0,2)
                if gameDoors[ChangeRandom] == 0:
                    amountWin += 1
                    loopStart += 1
                else:
                    amountLose += 1
                    loopStart += 1

    print("Win amount: ",amountWin,"\tLose amount: ",amountLose)

我做错了什么?我真的很感谢所有的帮助!提前致谢!

最佳答案

ChangeRandom = 0
while gameDoors[ChangeRandom] == gameDoors[inputUser]:
    ChangeRandom = randint(0,2)

这并不像你想象的那样。这不是检查 ChangeRandom 门是否与 inputUser 门相同,而是检查 ChangeRandom 门和 inputUser 是否相同code>door 具有相同的值——也就是说,他们要么都是赢家,要么都是输家。

也就是说,这甚至不是您想要做的。您想要做的是找到一扇不是用户输入的门,即失败者门,然后切换到另一扇不是用户输入的门。这可以通过对代码进行最小的更改来实现,如下所示:

other_wrong_door = next(c for c, v in enumerate(gameDoors) if v != 0 and c != inputUser)
new_door = next(c for c, _ in enumerate(gameDoors) if c != inputUser and c != other_wrong_door)

但说实话,这值得重新检查代码的结构。给我几分钟时间来解决这个问题,我将编辑这个答案,让您了解我将如何实现它。

import random

DOORS = [1, 0, 0]

def runonce(switch=False):
    user_choice = random.choice(DOORS)
    if user_choice == 1:
        # immediate winner
        if switch:
            # if you won before and switch doors, you must lose now
            return False
        else:
            new_doors = [0, 0]  # remove the user-selected winner
            new_doors = [0]     # remove another loser
            return bool(random.choice(new_doors))
            # of course, this is always `0`, but
            # sometimes it helps to show it. In production you
            # wouldn't bother writing the extra lines and just return False
    else:
        if switch:
            new_doors = [1, 0]  # remove the user-selected loser
            new_doors = [1]     # remove another loser
            return bool(random.choice(new_doors))
            # as above: this is always True, but....
        else:
            return False  # if you lost before and don't switch, well, you lost.

num_trials = int(input("How many trials?"))
no_switch_raw = [run_once(switch=False) for _ in range(num_trials)]
switch_raw = [run_once(switch=True) for _ in range(num_trials)]

no_switch_wins = sum(1 for r in no_switch_raw if r)
switch_wins = sum(1 for r in switch_raw if r)

no_switch_prob = no_switch_wins / num_trials * 100.0
switch_prob = switch_wins / num_trials * 100.0

print( "         WINS    LOSSES   %\n"
      f"SWITCH:  {switch_wins:>4}    {num_trials-switch_wins:>6}  {switch_prob:.02f}\n"
      f"NOSWITCH:{no_switch_wins:>4}    {num_trials-no_switch_wins:>6}  {no_switch_prob:.02f}")

关于python - Monty Hall 模拟未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44618935/

相关文章:

simulation - 如何在simpy中调试

Excel VBA 中的数组。在某些时候,它会放置 NA 而不是 value

python - 将 Linux Terminal 放入 wxPython 窗口

python - Numpy 会自动检测和使用 GPU 吗?

python - 在 Windows 中将 VIM 用于 Python IDE?

Python:如何通过下一个项目值链接列表中的元组

vhdl - 为什么 HDL 仿真(来自源代码)可以访问仿真器的 API?

python - 导入本地创建的模块

python - 语音识别引擎超时(python 3.7.4)

python-3.x - 将多分类列转换为 Pandas 中的两个类别