I created a simulation in Python for:
A) A player who sticks with the chosen door B) A player who switches door after hosts opens a door without a price.
For scenario A) I get 66% lose rate (33% win rate) which validates the paradox.
The puzzling part for me is when I run the simulation for scenario B), I keep getting a 55% loose rate (45% win rate). Yes, winning odds improve, but I thought I'd get a winning rate close to 66%. I am not sure if the simulation is wrong, or if it's correct.
Here is the code that simulates scenario B):
Created a Player class:
When creating a Player object, it randomly picks a door. Switch parameter allows me to control the behaviour (between switching doors or not)
from random import randrange
class Player:
def __init__(self, switch):
self.door = randrange(3)
self.switch = switch
def switch_door(self, open_door):
doors = range(3)
if(self.switch == True):
for door in doors:
if(door != self.door) and (door != open_door):
self.door = door
def get_door(self):
return self.door
Created a class Host: When creating a Host object, it randomly assigns the winning door (this is because the paradox uses the host's knowledge to open a loosing door)
from random import randrange
class Host:
def __init__(self):
self.door_prize = randrange(3)
def open_door(self, player_door):
doors = range(3)
for door in doors:
if (door != self.door_prize) and (door != player_door):
return door
def get_prize(self):
return self.door_prize
Main script:
import numpy as np
import matplotlib
from matplotlib import pyplot as plt
from player import Player
from host import Host
def win_price(player_door, prize_door):
if player_door == prize_door:
return "win"
else:
return "loose"
rounds = 100000
results = []
for i in range(rounds):
player = Player(True)
host = Host()
open_door = host.open_door(player.get_door())
player.switch_door(open_door)
results.append(win_price(player.get_door(), host.get_prize()))
outcome_labels = ["Loose", "Win"]
loose_count = 0
win_count = 0
for result in results:
if result == 'loose':
loose_count += 1
if result == 'win':
win_count += 1
results_count = [loose_count, win_count]
print(loose_count)
print(win_count)
plt.pie(results_count, labels=outcome_labels, autopct='%1d%%')
plt.show()
Is this simulation correct? I keep getting a 55%-45% loose-win ratio
Error 1:
Switch door error:
You go through the doors one by one. If the door isn't the open door and isn't the users current door the user switches. But if the user switches to a lower door we will then continue to the users original door which is no longer the users door and the user will switch back to the original.
Of for instance. If the user chooses door 2 and is shown door 3. The program will go through door 1, which not being the users current door nor the shown door, will be switch to the users door. But then the program goes to door 2, and door to is no longer the users door nor the shown door. So that gets switched back to the users door, and the end result is the users door is not switched.
Same thing if users chooses door 3. The user will switch to a lower door and then switch back.
So the solution is to break to loop
Solution 1:
Error 2: (Thanks to Joriki) for catching this
show door error.
If the player chooses the door with the prize then the host has two choices of doors to show. In the actual monty hall problem the host will randomly choose which of the two to choose. But in your program you have the host automatically.
Which doesn't change anything if the user does the hold or switch strategies. But it gives more information. If the player uses the strategy switch if the host shows you the higher of the two remaining doors--- the prize will always be in the lower door, and if the host shows the lower of the two remaining doors hold or switch it doesn't matter.
So you program has the folowing outcomes:
Prize is door 1, Player chooses door 1. Outcome. Host shows door two. Player switches to Door 3. LOSE (1-9 times) (This should actually be two 1-18 times options with host sometimes showing door three.)
Prize is door 1, Player chooses door 2. Outcome. Host shows door three. Player switches to door 1, but switches back to door 2. LOSE (1-9) times. (This should actually be a win.)
Prize is door 1, Player chooses door 3. Outcome: Host shows door three. Player switches to 1 and back to 3. LOSE (1-9)(This should actually be a win)
Prize is door 2, Player chooses door 1. Outcome: Host shows door 3. Player Switches to door 2. WIN (1-9). (As it should be.)
Prize is door 2, Player chooses door 2. Host shows door 1. Player switches to door 3. LOOSE (1-9) (This should be two 1-18 occurances when host shows door 3. If that had happened with the current swith_door program, player would have switched to door 1 and back to door 2 and win which he shouldn't.)
Prize is door 2, Player chooses door 3. Host shows door 1. Player switches to door 2, and then back to door 3. LOSE (1-9) (this should have been a win.)
Prize in door 3. Player chooses door 1. Host shows door 2. Player switches to door 3, WIN (1-9) (as it should be)
Prize in door 3. Player chooses door 2. Host shows door 1. Player switches to door 3, WIN (1-9) (as it should be)
Prize in door 3, Player chooses door 3. Host shows door 1. Player switchest to 2 and then back to 3. WIN (should be a LOSE and also should be two 1-18 events).
So WIN = $\frac 49 = 44$ and LOSE = $\frac 59= 56$.