About     Projects     GitHub     Now     Else

Modeling the Monty Hall Problem with Python

At first glance, the Monty Hall problem can seem counterintuitive, but, when viewed from the correct perspective, the appropriate strategy becomes abundantly apparent.


Although there are many excellent explanations for why the it is always a better strategy to change doors, after discussing the solution with one of the interns at the office, I thought it might be a handy excercise to write a simulator to model the outcomes for different strategies.


The code for the simulation in Python :

from random import randint

class MontyHall:
    The Monty Hall Problem
    def __init__(self,doors=3,change=False):
        Initialize game

        @param doors : an int used to generate the doors list from one up to the input number (must be at least 2).
        @param change : a boolean to determine whether to stay with the original door pick
        self.doors = [x for x in xrange(1,doors + 1)]
        self.change = change

    def play(self):
        Play game

        @return : a boolean representing whether the correct door was choosen

        #copy the doors list
        doors = self.doors + []
        #randomly assign the prize to one of the doors
        prize = doors[randint(0,len(doors) - 1)]

        #randomly assign a guess for which door the prize is behind
        choice = doors.pop(randint(0,len(doors) - 1))

        #open all unchosen doors except for one and call it the "alternative"
        #let the player select between the chosen door and the alternative
        #if the prize was not selected, make the alternative door the prize
        #otherwise, pick a door at random for the alternative
        if prize in doors:
            alternative = prize
            alternative = doors.pop(randint(0,len(doors) - 1))
        #if change is True, pick the alternative door
        #otherwise stay with the choosen door
        if self.change:
            choice = alternative
        #return True if the correct door was selected
        return prize == choice

    def test(self,iterations=1000):
        Test strategy

        @param iterations : 
        @return : a float representing the success rate for the chosen strategy
        score = 0
        i = 0
        while i < iterations:
            if self.play():
                score += 1
        return float(score) / iterations

m = MontyHall()
print m.test()

#change the default strategy from False to True
m = MontyHall(change=True)
print m.test()


Just as expected, over the course of 1000 trials, the simulator shows that the winning strategy is to always change doors.

Doors Strategy Trials Wins Losses Success Rate
3 Stay 1000 344 656 34.4%
3 Change 1000 662 338 66.2%
5 Stay 1000 224 776 22.4%
5 Change 1000 796 204 79.6%