Python-Monty-Hall模拟给出了切换和不切换的相同几率

Python-Monty-Hall模拟给出了切换和不切换的相同几率,python,simulation,Python,Simulation,我用Python创建了一个(相当复杂的)Monty Hall模拟,但是,当运行时,切换和非切换的几率相等,分别为33%和33%,因为我知道,在现实中,这不可能是事实,也不是事实。怎么了 import math import random Right = 0 def TestWithSwitch(): global Right wdoor = math.floor(random.random() * 3) doors = [0,0,0] doors[wdoor]

我用Python创建了一个(相当复杂的)Monty Hall模拟,但是,当运行时,切换和非切换的几率相等,分别为33%和33%,因为我知道,在现实中,这不可能是事实,也不是事实。怎么了

import math
import random

Right = 0
def TestWithSwitch():
    global Right
    wdoor = math.floor(random.random() * 3)
    doors = [0,0,0]
    doors[wdoor] = 1
    Ldoors = [0,0]
    i=0
    ##Declare winning door to be the winning door in the door Array

    for x in range(0, 3):
        if(x!=3):
            if(doors[x] != 1):
                Ldoors[i] = x
                i+=1
    ##Chose the losing doors to be the doors that aren't the winning door
    choice = math.floor(random.random() * 3)
    DoorOut = 0
    ##Pick a Choice
    LChose = False
    for y in range(0, 2):
        if(y!= 2):
            if(Ldoors[y] == choice):
                DoorOut = Ldoors[(y+1)%2]
                LChose = True
    if(LChose == False):
        DoorOut = Ldoors[math.floor(random.random() * 2)]
    Reserved = [DoorOut, choice]

##DoorOut is chosen from any of the losing doors we didn't pick as our choice, and is the door the computer is told doesn't have the prize
    for z in range(0, 3):
        if(z!= 3):
            if(z in Reserved == False):
                choice = z
                ##Make our new choice the other choice that we didn't previously choose
    if(choice == wdoor):
        Right+=1

def TestNoSwitch():
    global Right
    wdoor = math.floor(random.random() * 3)
    doors = [0,0,0]
    doors[wdoor] = 1
    Ldoors = [0,0]
    i=0


    for x in range(0, 3):
        if(x!=3):
            if(doors[x] != 1):
                Ldoors[i] = x
                i+=1
    choice = math.floor(random.random() * 3)
    if(choice == wdoor):
        Right+=1



for j in range(1, 10000):
    ## TestWithSwitch() and TestNoSwitch() both result in about 1/3. You can test by putting either function in.
    if(j == 9999):
        print(Right/10000)
我知道转换应该返回66%的几率,而不应该返回33%的几率。我收到的赔率加起来甚至不到100%,但大约有三分之二,这是概率上不可能的

首先

for x in range(0, 3):
    if(x!=3):          # redundant: x will never be 3
另一方面,通过全局变量收集函数结果是一种邪恶

我会这样做:

from random import choice

DOORS = "ABC"

def pick():
    """
    Return a door at random
    """
    return choice(DOORS)

def always_switch():
    """
    Monty Hall strategy - when offered a choice, always switch
    """
    guess = pick()
    actual = pick()
    return not guess == actual

def never_switch():
    """
    Monty Hall strategy - when offered a choice, never switch
    """
    guess = pick()
    actual = pick()
    return guess == actual

def test(fn, tries):
    """
    Return the fraction of calls to fn which return True
    """
    return sum(1 for _ in range(tries) if fn()) / tries

def main():
    """
    Simulate the Monty Hall problem
    """
    tries = 10000

    pct = 100. * test(always_switch, tries)
    print("Test (always switch): %0.1f %%" % (pct,))

    pct = 100. * test(never_switch, tries)
    print("Test (never switch): %0.1f %%" % (pct,))

if __name__ == "__main__":
    main()
它产生的输出像

Test (always switch): 66.3 %
Test (never switch): 32.7 %
注意:您可以通过将
guess=pick()
任意替换为
guess=“A”
(不丧失通用性)来加快速度

for x in range(0, 3):
    if(x!=3):          # redundant: x will never be 3
另一方面,通过全局变量收集函数结果是一种邪恶

我会这样做:

from random import choice

DOORS = "ABC"

def pick():
    """
    Return a door at random
    """
    return choice(DOORS)

def always_switch():
    """
    Monty Hall strategy - when offered a choice, always switch
    """
    guess = pick()
    actual = pick()
    return not guess == actual

def never_switch():
    """
    Monty Hall strategy - when offered a choice, never switch
    """
    guess = pick()
    actual = pick()
    return guess == actual

def test(fn, tries):
    """
    Return the fraction of calls to fn which return True
    """
    return sum(1 for _ in range(tries) if fn()) / tries

def main():
    """
    Simulate the Monty Hall problem
    """
    tries = 10000

    pct = 100. * test(always_switch, tries)
    print("Test (always switch): %0.1f %%" % (pct,))

    pct = 100. * test(never_switch, tries)
    print("Test (never switch): %0.1f %%" % (pct,))

if __name__ == "__main__":
    main()
它产生的输出像

Test (always switch): 66.3 %
Test (never switch): 32.7 %
注意:您可以通过将
guess=pick()
任意替换为
guess=“A”
(不丧失通用性)来加快速度。

问题在于:

if(z in Reserved == False):
这将被评估为a,并将始终导致false

if(z in Reserved and Reserved == False):
使用括号创建正确的操作员顺序:

if((z in Reserved) == False):
或者最好使用显式的“不在”运算符:

if(z not in Reserved):
问题在于:

if(z in Reserved == False):
这将被评估为a,并将始终导致false

if(z in Reserved and Reserved == False):
使用括号创建正确的操作员顺序:

if((z in Reserved) == False):
或者最好使用显式的“不在”运算符:

if(z not in Reserved):

您的
TestWithSwitch
缩进被破坏。另外,您使它变得比需要的更复杂。对于那些想知道的人,我使用了函数
math.floor(random.random()*3))
,因为我不知道random的randintfunction@HughBothwell我修正了我的压痕。你知道为什么回报率相等吗?我知道这比必要的要复杂得多,我就是这样做的。压痕仍然不清楚correct@DavidZ那里我想它没有保存。你的
TestWithSwitch
缩进被破坏了。另外,您使它变得比需要的更复杂。对于那些想知道的人,我使用了函数
math.floor(random.random()*3))
,因为我不知道random的randintfunction@HughBothwell我修正了我的压痕。你知道为什么回报率相等吗?我知道这比必要的要复杂得多,我就是这样做的。压痕仍然不清楚correct@DavidZ那里我猜它没有保存。尽管之后你用开关
测试得到了1.66。NineBerry,我使用的是一个旧版本的操作码,它有一个缩进错误。使用问题中的最新代码,您建议的编辑确实会得到正确的答案+1尽管使用开关
测试得到1.66。但是,我使用的是一个旧版本的OP代码,它有一个缩进错误。使用问题中的最新代码,您建议的编辑确实会得到正确的答案+1这个答案对我帮助更大,但我选择了另一个答案作为正确答案,因为它有助于调试。这个答案对我帮助更大,但我选择了另一个答案作为正确答案,因为它有助于调试。