对蒙蒂·霍尔来说,这是一个好的还是坏的“模拟”?怎么会?

2024-10-02 16:30:57 发布

您现在位置:Python中文网/ 问答频道 /正文

在昨天的课上,我们试图向一位朋友解释Monty Hall problem,最后我们用Python编写了代码,以证明如果你总是交换,你会赢2/3次。我们想到了这个:

import random as r

#iterations = int(raw_input("How many iterations? >> "))
iterations = 100000

doors = ["goat", "goat", "car"]
wins = 0.0
losses = 0.0

for i in range(iterations):
    n = r.randrange(0,3)

    choice = doors[n]
    if n == 0:
        #print "You chose door 1."
        #print "Monty opens door 2. There is a goat behind this door."
        #print "You swapped to door 3."
        wins += 1
        #print "You won a " + doors[2] + "\n"
    elif n == 1:
        #print "You chose door 2."
        #print "Monty opens door 1. There is a goat behind this door."
        #print "You swapped to door 3."
        wins += 1
        #print "You won a " + doors[2] + "\n"
    elif n == 2:
        #print "You chose door 3."
        #print "Monty opens door 2. There is a goat behind this door."
        #print "You swapped to door 1."
        losses += 1
        #print "You won a " + doors[0] + "\n"
    else:
        print "You screwed up"

percentage = (wins/iterations) * 100
print "Wins: " + str(wins)
print "Losses: " + str(losses)
print "You won " + str(percentage) + "% of the time"

我的朋友认为这是一个很好的解决方法(也是一个很好的模拟),但我有我的怀疑和担心。它真的足够随机吗?

我的问题是所有的选择都是硬编码的。

这是对蒙蒂霍尔问题的好的还是坏的“模拟”?怎么会?

你能想出一个更好的版本吗?


Tags: youisthereprintlossesmontywonopens
3条回答

你提到所有的选择都是硬编码的。但如果你仔细观察,你会发现你认为的“选择”实际上根本不是选择。蒙蒂的决定没有失去一般性,因为他总是选择有山羊在后面的门。你的交换总是由蒙蒂的选择决定的,既然蒙蒂的“选择”实际上不是一个选择,你也不是。你的模拟给出了正确的结果。。

我喜欢这样的东西。


#!/usr/bin/python                                                                                                            
import random
CAR   = 1
GOAT  = 0

def one_trial( doors, switch=False ):
    """One trial of the Monty Hall contest."""

    random.shuffle( doors )
    first_choice = doors.pop( )
    if switch==False:
        return first_choice
    elif doors.__contains__(CAR):
        return CAR
    else:
        return GOAT


def n_trials( switch=False, n=10 ):
    """Play the game N times and return some stats."""
    wins = 0
    for n in xrange(n):
        doors = [CAR, GOAT, GOAT]
        wins += one_trial( doors, switch=switch )

    print "won:", wins, "lost:", (n-wins), "avg:", (float(wins)/float(n))


if __name__=="__main__":
    import sys
    n_trials( switch=eval(sys.argv[1]), n=int(sys.argv[2]) )

$ ./montyhall.py True 10000
won: 6744 lost: 3255 avg: 0.674467446745

您的解决方案很好,但是如果您希望对所提出的问题进行更严格的模拟(以及更高质量的Python;-),请尝试:

import random

iterations = 100000

doors = ["goat"] * 2 + ["car"]
change_wins = 0
change_loses = 0

for i in xrange(iterations):
    random.shuffle(doors)
    # you pick door n:
    n = random.randrange(3)
    # monty picks door k, k!=n and doors[k]!="car"
    sequence = range(3)
    random.shuffle(sequence)
    for k in sequence:
        if k == n or doors[k] == "car":
            continue
    # now if you change, you lose iff doors[n]=="car"
    if doors[n] == "car":
        change_loses += 1
    else:
        change_wins += 1

print "Changing has %s wins and %s losses" % (change_wins, change_loses)
perc = (100.0 * change_wins) / (change_wins + change_loses)
print "IOW, by changing you win %.1f%% of the time" % perc

典型的输出是:

Changing has 66721 wins and 33279 losses
IOW, by changing you win 66.7% of the time

相关问题 更多 >