Search code examples
pythonlanguage-agnosticprobability

Is this a good or bad 'simulation' for Monty Hall? How come?


Through trying to explain the Monty Hall problem to a friend during class yesterday, we ended up coding it in Python to prove that if you always swap, you will win 2/3 times. We came up with this:

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"

My friend thought this was a good way of going about it (and is a good simulation for it), but I have my doubts and concerns. Is it actually random enough?

The problem I have with it is that the all choices are kind of hard coded in.

Is this a good or bad 'simulation' for the Monty Hall problem? How come?

Can you come up with a better version?


Solution

  • Your solution is fine, but if you want a stricter simulation of the problem as posed (and somewhat higher-quality Python;-), try:

    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
    

    a typical output is:

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