Saturday, April 12, 2008

Demonstrating Monty Hall in Python

There was a recent article on the Monty Hall problem in the New York Times blog TiernyLab.

The problem is this: You're on a game show, and there are three doors you may choose from. One door contains a car (or something else that's desirable) and the other two doors contain goats (or something else that's undesirable). After you pick your first door (this is the important part), the host must open another door and show you a goat. You then may choose whether to stick with your original choice or switch doors.

Should you switch doors?

Most people's response is "it doesn't matter, because the car could be behind either door, so it's the same as if I'd just been given the choice of the two doors, so it's 50-50". But that's not true, and here's why:

Monty's Constraint, as I call it, changes the odds. When you first selected a door, you had a 1/3 chance of choosing the car, and you had a 2/3 chance of choosing a goat. If you were to switch at this point, before Monty (the host) opens another door, then your odds would still be the same.

But, because Monty has to choose a door with a goat behind it to show you, there are two possible scenarios. First, if you picked the car (a 1/3 probability), then Monty can show you either of the two remaining doors as he pleases. But, if you picked a goat (2/3 probability), then the door he doesn't pick must contain the car.

Therefore, your odds of winning if you switch are 2/3 (because those are the odds that you originally picked a goat) and your odds of winning if you stay are 1/3 (the original odds that you picked the car).

Don't believe me? Steve didn't, at first. So I wrote a little program to prove it. It's in Python, so you shouldn't have any trouble understanding it, even if you're not a programmer.

Link: Python interpretor.

The Code:

import random

switchWins = 0
stayWins = 0

CAR = 1
GOAT = 0

for i in range(0,10000):

# set up doors. the set of doors is an array of two 0s and one 1.
# The 1 represents the car.
# start off with an empty set
doors = [GOAT, GOAT, GOAT]

# choose a door to have a car
carDoor = random.randint(0,2)

doors[carDoor] = CAR


# choose door (player)
playerDoor = 1

# choose door (monty). We use this to ensure monty
# randomly chooses a goat door.
montyDoor = random.randint(0,2)

# if the door monty picks has a car, or if the door he picks is
# the player's door, we have to pick again.
while doors[montyDoor] == CAR or montyDoor == playerDoor:

montyDoor = random.randint(0,2)

# There are only two doors left. If the player's door doesn't have
# a car, then the player would win by switching, so count it

if doors[playerDoor] != CAR:
switchWins += 1

# Conversely, if the player's door does have a car, the player
# would win by staying, so count that
if doors[playerDoor] == CAR:
stayWins += 1

print switchWins, stayWins

No comments:

The City Born Great - How Long 'Til Black Future Month?

The second story in N. K. Jemisin's anthology How Long 'Til Black Future Month? , "The City Born Great," is an exciting ta...