我正在尝试理解Monty Hall问题的这个解决方案,我理解大部分代码,但我被困在两个部分。
以下是代码,但具体来说我坚持这两部分
result[bad] = np.random.randint(0,3, bad.sum())
以及整个switch_guess
函数。
如果有人能用简单的英语向我解释这将是非常棒的。
#Simulates picking a prize door
def simulate_prizedoor(nsim):
return np.random.randint(0,3,(nsim))
#Simulates the doors guessed
def simulate_guesses(nsim):
return np.zeros(nsim, dtype=np.int)
#Simulates the "game host" showing whats behind a door
def goat_door(prize_doors, guesses):
result = np.random.randint(0,3, prize_doors.size)
while True:
bad = (result == prize_doors) | (result == guesses)
if not bad.any():
return result
result[bad] = np.random.randint(0,3, bad.sum())
#Used to change your guess
def switch_guess(guesses, goat_doors):
result = np.zeros(guesses.size)
switch = {(0, 1): 2, (0, 2): 1, (1, 0): 2, (1, 2): 1, (2, 0): 1, (2, 1): 0}
for i in [0,1,2]:
#print "i = ", i
for j in [0,1,2]:
#print "j = ", j
mask = (guesses == i) & (goat_doors == j)
#print "mask = ", mask
if not mask.any():
continue
result = np.where(mask, np.ones_like(result) * switch[(i, j)], result)
return result
#Calculates the win percentage
def win_percentage(guesses, prizedoors):
return 100 * (guesses == prizedoors).mean()
#The code to pull everything together
nsim = 10000
#keep guesses
print "Win percentage when keeping original door"
print win_percentage(simulate_prizedoor(nsim), simulate_guesses(nsim))
#switch
pd = simulate_prizedoor(nsim)
guess = simulate_guesses(nsim)
goats = goat_door(pd, guess)
guess = switch_guess(guess, goats)
print "Win percentage when switching doors"
print win_percentage(pd, guess)
答案 0 :(得分:2)
...特别是我坚持这两部分
result[bad] = np.random.randint(0,3, bad.sum())
让我们把它分解成碎片。将10000
缩小到较小的值可能会有所帮助,例如5
,这样您就可以打印出值(使用print
调用,或者在调试器中)并查看'继续。
当我们启动此功能时,prize_doors
将有0
到2
的5个随机值,如2 2 0 1 2
,而guesses
将有5个值,全部为0,如0 0 0 0 0
。因此,result
将从0到2的5个随机值开始,例如0 2 2 0 1
。
每次第一次循环,bad
将是5个bool
值的列表,如果True
中的对应值与相应的值匹配,则每个值result
在prize_doors
或guesses
中。因此,在此示例中,True True False True False
,因为猜测#1与prize_doors
匹配,并且猜测#0和#3匹配goats
。
不幸的是,我们只是永远绕过那个循环,因为循环中没有任何内容可以修改result
,因此bad
将会是相同的永远,永远做同样的检查总是会返回相同的值。
但是如果你缩进result[bad] = …
行,那么它就会在循环中缩进,这会改变一切。所以,让我们假设你应该做的是什么,而你只是把它复制错了。
当被视为数字时,True
和False
分别具有值1
和0
。因此,bad.sum()
是bad
中有多少匹配的计数 - 在这种情况下,3
。
因此,np.random.randint(0, 3, bad.sum())
从0
到2
选择3个随机值,让我们说1 0 1
。
现在,result[bad]
选择result
中bad
的相应值为True的所有元素,因此在此示例中为result[0]
, result[1]
和result[3]
。
因此,我们最终将1 0 1
分配给这三个选定的位置,因此result
现在为1 0 2 1 1
。
因此,下次循环时,bad
现在为True False False False False
。我们仍然至少有一个True
值,因此我们再次运行result[bad] =
行。这一次,bad.sum()
为1
,因此我们选择1个随机值,让我们说0
,然后我们将该值分配给result[0]
,所以{ {1}}现在是result
。
下一次,0 0 2 1 1
现在是bad
,因此False False False False False
是bad.any()
,所以我们已经完成了。
换句话说,每次通过时,我们都会采用与奖品门或山羊门不匹配的所有价值,并为他们选择一扇新门,直到最后没有这样的价值。
答案 1 :(得分:0)
它也使我感到困惑,直到5分钟前我终于明白了。 由于第一个问题已经解决,我只谈第二个问题。
直觉是这样的:给定一系列(猜测,山羊门),在(i,j)循环中,总有一些模拟(例如,模拟[0]和模拟[5])'命中'通过(i,j),即说法,第0和第5次模拟猜测我和山羊门j。
此示例中的变量mask
记录0和5。然后可以确定第0和第5的结果,因为在这些模拟中,切换到的唯一可能的门由i和j确定。因此,np.where
刷新会导致这些模拟,保持其他模拟不变。
直觉就在上面。如果你想知道我在说什么,你需要知道np.where
如何工作。祝你好运。