Python Monty Hall 模拟给出了切换和不切换的相同几率
Python Monty Hall simulation giving equal odds for both switching and not
我在 Python 中创建了一个(相当复杂的)Monty Hall 模拟,但是,当 运行、return 时,对于 Switching 和 not,当我要知道,在现实中,这不可能,也不是这样。怎么了?
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)
我知道切换应该 return 66% 的几率,而不应该 return 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"
来加快速度(不失一般性)。
问题在这里:
if(z in Reserved == False):
这被评估为 chained comparison,结果始终为 false。
if(z in Reserved and Reserved == False):
使用括号创建正确的运算符顺序:
if((z in Reserved) == False):
或者更好地使用显式 "not in" 运算符:
if(z not in Reserved):
我在 Python 中创建了一个(相当复杂的)Monty Hall 模拟,但是,当 运行、return 时,对于 Switching 和 not,当我要知道,在现实中,这不可能,也不是这样。怎么了?
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)
我知道切换应该 return 66% 的几率,而不应该 return 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"
来加快速度(不失一般性)。
问题在这里:
if(z in Reserved == False):
这被评估为 chained comparison,结果始终为 false。
if(z in Reserved and Reserved == False):
使用括号创建正确的运算符顺序:
if((z in Reserved) == False):
或者更好地使用显式 "not in" 运算符:
if(z not in Reserved):