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

Saturday, April 05, 2008

A sandbox for real life (a ramble)

Every so often I read something that proposes some change that will have some sort of desirable effect. (Being an anarchist, I believe this to be true about anarchy.) But, we live in a situation where it is not only impractical to experiment on every idea that comes our way, it would arguably be immoral. Communism, for example, at least as practiced in Soviet Russia, in which the suffering of the poor was worsened by tyranny.

Now, we can run simulations and create models, but these all suffer from simplification because we have to choose what to leave out of the model or simulation in order to make it generate results in a reasonable amount of time.

So, I wish we had what programmers call a 'sandbox' for real life; a place where we could test theories out in conditions as close to the real world as possible, preferably identical. A place where we could get the results of a hundred years in a few days (or less!).

Of course, that does make me wonder: is the suffering of the sandbox any less than real suffering? Does the fact that it all gets washed away when you're done cleanse the wrongs?

Anyway, enough ramble for now.