2013-04-25 6 views
7

Ich versuche die Monty Hall Problem (weil ich aus dem Buch Think Statistics gelesen habe, dass ein Typ besonders überzeugte erst nachdem ich eine Computersimulation gesehen hatte) in C#, der Programmiersprache, die mir am vertrautesten ist. Mein Szenario ist so, dass die Position des Preises zufällig ist (in jedem Lauf), meine Wahl ist zufällig und die Wahl des Spielers, die Tür zu öffnen, ist zufällig (es kann nicht zufällig sein, wenn ich den Nicht-Preis gewählt habe).Monty Hall Programm Simulation (C#)

Überraschenderweise erreicht mein Programm das Ergebnis einer 50: 50-Gewinnchance, egal ob ich wechsle oder nicht. Hier ist der Code, um es (verzeihen Sie mir für die Langwierigkeit):

class Program 
{ 
    static void Main(string[] args) 
    { 
     Random rand = new Random(); 

     int noSwitchWins = RunGames(rand, false, 10000); 
     int switchWins = RunGames(rand, true, 10000); 

     Console.WriteLine(string.Format("If you don't switch, you will win {0} out of 1000 games.", noSwitchWins)); 
     Console.WriteLine(string.Format("If you switch, you will win {0} out of 1000 games.", switchWins)); 

     Console.ReadLine(); 
    } 

    static int RunGames(Random rand, bool doSwitch, int numberOfRuns) 
    { 
     int counter = 0; 

     for (int i = 0; i < numberOfRuns; i++) 
     { 
      bool isWin = RunGame(rand, doSwitch); 
      if (isWin) 
       counter++; 
     } 

     return counter; 
    } 

    static bool RunGame(Random rand, bool doSwitch) 
    { 
     int prize = rand.Next(0, 2); 
     int selection = rand.Next(0, 2); 

     // available choices 
     List<Choice> choices = new List<Choice> { new Choice(), new Choice(), new Choice() }; 
     choices[prize].IsPrize = true; 
     choices[selection].IsSelected = true; 
     Choice selectedChoice = choices[selection]; 
     int randomlyDisplayedDoor = rand.Next(0, 1); 

     // one of the choices are displayed 
     var choicesToDisplay = choices.Where(x => !x.IsSelected && !x.IsPrize); 
     var displayedChoice = choicesToDisplay.ElementAt(choicesToDisplay.Count() == 1 ? 0 : randomlyDisplayedDoor); 
     choices.Remove(displayedChoice); 

     // would you like to switch? 
     if (doSwitch) 
     { 
      Choice initialChoice = choices.Where(x => x.IsSelected).FirstOrDefault(); 
      selectedChoice = choices.Where(x => !x.IsSelected).FirstOrDefault(); 
      selectedChoice.IsSelected = true; 
     } 

     return selectedChoice.IsPrize; 
    } 
} 

class Choice 
{ 
    public bool IsPrize = false; 
    public bool IsSelected = false; 
} 

Das ist ganz für mein eigenes Interesse willen, und ich schrieb es in der Art und Weise die meisten vertraut und bequem zu mir. Fühlen Sie sich frei, Ihre eigene Meinung und Kritik zu bieten, vielen Dank!

Antwort

5
rand.Next(0,2) 

gibt nur 0 oder 1 zurück; die obere Grenze ist exklusive. Du wählst niemals die dritte Tür aus (außer du wechselst), und die dritte Tür hat niemals den Preis. Sie modellieren das falsche Problem.

Versuchen Sie stattdessen:

rand.Next(0,3) 

Ebenso:

int randomlyDisplayedDoor = rand.Next(0, 1); 

nur wählt immer die erste der Kandidaten Türen; sein sollte:

int randomlyDisplayedDoor = rand.Next(0, 2); 

Jetzt erhalten wir:

If you don't switch, you will win 3320 out of 1000 games. 
If you switch, you will win 6639 out of 1000 games. 

Hinweis - die obere Grenze ist inklusive wenn gleich - das heißt rand.Next(1,1) immer wieder 1.

+0

Sieht aus wie ich auf der Randomisierung Teil vermasselt, danke! – matt

1

Siehe Random.Next(minValue, maxValue)

Parameter

minValue Typ: System.Int32 Das im Preis inbegriffene untere Grenze der Zufallszahl zurückgegeben.

maxValue Typ: System.Int32 Die exklusive Obergrenze der zurückgegebenen Zufallszahl. maxValue muss größer oder gleich minValue sein.

1

zu Marcs Antwort hinzuzufügen, können Sie auch Random.Next(Int32) da Ihre untere Grenze 0 verwenden können, so dass es einfach sein würde:

rand.Next(3)