Sunday 2 September 2012

Monty Hall Problem Simulation

Introduction:


I was watching the show Numb3rs the other day and the Monty Hall Problem came up. After some research I found that I could work out the problem experimentally with a virtually infinite sample size. For those of you who don't know about the Monty Hall problem, it was a probability puzzle loosely based on a popular game show which was hosted by Monty Hall called 'Lets make a deal' . Here is an excerpt from Wikipedia which goes over the exact details:

 
Wikipedia: " Suppose you're on a game show, and you're given the choice of three doors:
Behind one door is a car; behind the others, goats. You pick a door, say No. 1
[but the door is not opened], and the host, who knows what's behind the doors,
opens another door, say No. 3, which has a goat. He then says to you, "Do you
want to pick door No. 2?" Is it to your advantage to switch your choice?" 


The solution to the puzzle is very interesting. According to probability theory the best choice is to switch the choice of your door. This is outrageously counter intuitive,  your probably saying: "how could that possibly make any difference!" - right? That was exactly my reaction, and I decided to write a simple program to simulate the problem and show me, practically why this is the best decision to make. Before writing the program I had to first understand the fundamentals of the problem, and, after many hours in front of the laptop I finally found the solution.


The Experiment:

Brief:
Using the following code I am attempting to demonstrate the increase in 'success rate'

achieved by switching the choice of door, after one door is taken out of the equation

by the game show host.

Hypothesis:
Before the choice is switched a 33% success rate is expected, once a door is removed and 
the choice is switched I expect the rate to increase above 33.33%.

Conclusion:
Ones chances would actually improve twofold if one switched the choice of door after one 
was removed out of the equation.

Closing Note:
I actually worked this problem out on paper, calculating probability of success before and after switching the chosen door. However after I found the final result of a 1/3 probability without switching, and a 2/3 probability with switching I needed a practical proof; I needed to carry out the experiment in real life. I started by making a large chart and using a random number generator to pick the doors, after about 50 samples the relationship was not evident and I was incredibly bored. I finally decided to use Processing to run the experiment instead so that I could have as large a sample as I wanted and it would be far less tedious.



The Program:

note: 
Iterations: Number of samples taken
Code Speed: made for personal reference, indicates the average time for one sample to be taken in miliseconds
Keep rate: success rate if he keeps the same door
Switch rate: the success rate if he switches the door


The source code:

int host;
int choice;
int reChoice;
int DoorRemove;
int Removed; 

float iterations = 1; 
float correctA = 0;
float correctB = 0;

void setup() {
  frameRate(9001); // OVER 9000!
  size(150, 150);
}

void draw() {
  //calling all functions calling all functions
  background(200);

  ChooseCarDoor();
  Contestant();

  Stats(choice,0, "Keep ");
  Stats(0,reChoice, "Switch ");

  iterations++;
}



void ChooseCarDoor() {      //This funtion decides which door(1 2 or 3) the car 
  host = int(random(1, 4)); //is behind.
}


void Contestant() {  //This function decides which door the contestant chooses
  choice = int(random(1, 4));
  Removed = removeDoor(choice, host);
  reChoice = 6 - choice - Removed;
}

int removeDoor(int DoorChosen, int DoorCar) {  // This function removes a the 
                                               // door which doesnt have a car
                                               // behind it and also isn't the 
                                               // choice of the contestant
  if (DoorChosen != DoorCar) {                 
    DoorRemove = 6 -DoorChosen -DoorCar;      //I'm very Proud of this bit of 
                                              //code here, it finds out
                                              // which door to remove by simple
                                              // subtractiom
  }
  else if (DoorChosen == 1) {
    DoorRemove = int(random(2, 4));
  }
  else if (DoorChosen == 2) {
    if (int(random(1, 3))==1) {
      DoorRemove = 1;
    }
    else {
      DoorRemove = 3;
    }
  }
  else if (DoorChosen == 3) {
    DoorRemove =  int(random(1, 3));
  }

  return DoorRemove;
}



void Stats(int StatsInA, int StatsInB, String strategy) { //This function is whe-
                                                          //re the success rates 
                                                          //for the two strategi-                                                          //es is determined
  if (StatsInA==host) {
    correctA++;
  }
  if (StatsInB==host) {
    correctB++;
  }



  float rateA = (correctA/iterations)*100;
  float rateB = (correctB/iterations)*100;

  fill(0);
  text("Iterations: " + iterations, 5, 15);
  text("Code Speed: " + millis()/iterations, 5, 30); //In milliseconds per loop
  
  if(StatsInB == 0){
  text(strategy + "Rate: " + rateA + "%", 5, 45);
  }else{
  text(strategy + "Rate: " + rateB + "%", 5, 60);
  }
}

No comments:

Post a Comment