Created
December 17, 2012 09:03
-
-
Save kiriappeee/4316871 to your computer and use it in GitHub Desktop.
Testing the Monty Hall Problem
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""As much as I understood the theorems of the monty hall problem | |
my brain simply refused to take it in and accept, so I wrote a very quick (and dirty) script to just test it out. | |
The script randomly generates two goats (designated as 0) and a car (designated by 1) for three doors (stored in a dictionary. I don't know why I | |
chose that. Anyway. Here's the script... And it works. Funnily enough when writing the program I kept having snippets of thoughts on how staying | |
with your old choice would leave you at 33% anyways since you didn't take advantage of the situation of knowing one door which had a goat behind it | |
That prompted me to write the normal test where based on intuition, you'd stick with the door you picked originally. And yes, everything checks out. | |
Edit: I also thought of the case of what if the game host reveals a door behind which there is a goat BEFORE you make your first pick. | |
Isn't that like the first scenario but the order just reversed? Apparently not. The results move down to 50-50. My mind has been blown. | |
In the face of math, trust not your intuition I guess. Oh, and I included results at the bottom. | |
""" | |
import random | |
"""this is the standard monty test. Works as follows | |
Pick a random door. | |
Host reveals a door behind which there is a goat | |
You are mathematical genius so you switch doors | |
Resulted in ~66% win ratio | |
""" | |
def montyTest(): | |
wins = 0 | |
losses = 0 | |
for i in range(0,100000): | |
random.seed() | |
doors = {1:0,2:0,3:0} | |
doors[1] = random.randint(0,1) | |
if doors[1] == 1: | |
doors[2] = doors[3] = 0 | |
else: | |
doors[2] = random.randint(0,1) | |
doors[3] = 1 - doors[2] | |
#print ('door 1: %d , door 2: %d, door 3: %d' % (doors.get(1),doors.get(2),doors.get(3))) | |
#logic for picking the door here | |
#randomly pick the first door | |
pick = random.randint(1,3) | |
"""if doors[pick] == 1: | |
print 'first door was car' | |
else: | |
print 'first door was goat'""" | |
#since the monty hall problem means we discard our first choice anyway, we pop it out of the list | |
doors.pop(pick) | |
#search for a door with a goat behind in and remove that door (the host of the show does this in the monty hall problem) | |
for k in doors.keys(): | |
if doors[k] == 0: | |
doors.pop(k) | |
break | |
#which leaves us with the only door remaining. For all we know we could have discarded a car in the first one. | |
if doors.get(doors.keys()[0]) == 1: | |
wins += 1 | |
else: | |
losses += 1 | |
print 'wins: ' + str(wins) | |
print 'losses: ' + str(losses) | |
"""This is the monty hall test for non mathematicians | |
Pick a door at random | |
Host revelas a door behind which there is a goat | |
You are stubborn and don't switch because of your intuition | |
Resulted in ~33% win ratio | |
""" | |
def normalTest(): | |
wins = 0 | |
losses = 0 | |
for i in range(0,100000): | |
random.seed() | |
doors = {1:0,2:0,3:0} | |
doors[1] = random.randint(0,1) | |
if doors[1] == 1: | |
doors[2] = doors[3] = 0 | |
else: | |
doors[2] = random.randint(0,1) | |
doors[3] = 1 - doors[2] | |
#print ('door 1: %d , door 2: %d, door 3: %d' % (doors.get(1),doors.get(2),doors.get(3))) | |
#logic for picking the door here | |
#randomly pick the first door | |
pick = random.randint(1,3) | |
"""if doors[pick] == 1: | |
print 'first door was car' | |
else: | |
print 'first door was goat'""" | |
#in this one, since we are going to stick with the door choice anyway, we stop the test here. | |
if doors.get(pick) == 1: | |
wins += 1 | |
else: | |
losses += 1 | |
print 'wins: ' + str(wins) | |
print 'losses: ' + str(losses) | |
"""This may or may not fall under a monty hall scenario but it was an interesting discussion. Scenario is as follows | |
Before you pick at random, the host reveals a door behind which there is a goat | |
You pick a door at random | |
Resulted in ~50% win ratio | |
Note - Even if you changed logic where if you randomly picked a door behind which there was a goat then you win and vice versa (the equivalent of picking | |
two doors... sort of) you'd still end up with ~50% win ratio. | |
""" | |
def abnormalTest(): | |
wins = 0 | |
losses = 0 | |
for i in range(0,100000): | |
random.seed() | |
doors = {1:0,2:0,3:0} | |
doors[1] = random.randint(0,1) | |
if doors[1] == 1: | |
doors[2] = doors[3] = 0 | |
else: | |
doors[2] = random.randint(0,1) | |
doors[3] = 1 - doors[2] | |
for k in doors.keys(): | |
if doors[k] == 0: | |
doors.pop(k) | |
break | |
if doors.get(doors.keys()[random.randint(0,1)]) == 1: | |
wins += 1 | |
else: | |
losses+= 1 | |
print 'wins: ' + str(wins) | |
print 'losses: ' + str(losses) | |
"""results of the tests are as follows. | |
Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit (AMD64)] on win32 | |
Type "help", "copyright", "credits" or "license" for more information. | |
>>> import monty | |
>>> monty.montyTest() | |
wins: 66598 | |
losses: 33402 | |
>>> monty.abnormalTest() | |
wins: 50253 | |
losses: 49747 | |
>>> monty.abnormalTest() | |
wins: 50070 | |
losses: 49930 | |
>>> monty.abnormalTest() | |
wins: 49719 | |
losses: 50281 | |
>>> monty.abnormalTest() | |
wins: 49791 | |
losses: 50209 | |
>>> monty.normalTest() | |
wins: 33317 | |
losses: 66683 | |
>>> | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment