2013-04-25 32 views
7

Tôi đang cố gắng mô phỏng số Monty Hall Problem (vì tôi đọc từ cuốn sách Think Statistics rằng một chàng trai cụ thể đã bị thuyết phục chỉ sau khi nhìn thấy một mô phỏng máy tính) trong C#, ngôn ngữ lập trình quen thuộc nhất với tôi. Kịch bản của tôi là như vậy mà vị trí của giải thưởng là ngẫu nhiên (trong mỗi lần chạy), lựa chọn của tôi là ngẫu nhiên, và sự lựa chọn của máy chủ trò chơi mở cửa là ngẫu nhiên (nó không thể ngẫu nhiên nếu tôi chọn không giải thưởng).Mô phỏng Chương trình Monty Hall (C#)

Đáng ngạc nhiên là chương trình của tôi đạt được kết quả 50:50 cơ hội chiến thắng cho dù tôi có chuyển đổi hay không. Đây là mã cho nó (tha thứ cho tôi về độ dài):

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; 
} 

Điều này hoàn toàn vì lợi ích của riêng tôi, và tôi đã viết nó theo cách quen thuộc và thoải mái nhất với tôi. Đừng cảm thấy tự do để đưa ra ý kiến ​​và phê bình của riêng bạn, cảm ơn bạn rất nhiều!

Trả lời

5
rand.Next(0,2) 

chỉ trả về 0 hoặc 1; giới hạn trên là độc quyền. Bạn không bao giờ chọn cánh cửa thứ ba (trừ khi bạn chuyển đổi), và cánh cửa thứ ba không bao giờ có giải thưởng. Bạn đang mô hình hóa vấn đề sai.

Hãy thử thay vì:

rand.Next(0,3) 

Tương tự như vậy:

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

chỉ bao giờ lựa chọn đầu tiên của cửa thành viên; nên là:

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

Bây giờ chúng ta nhận được:

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

Lưu ý - các giới hạn trên là bao gồm khi bằng - ví dụ: rand.Next(1,1) luôn trả 1.

+0

Hình như tôi sai lầm trên phần ngẫu nhiên, cảm ơn! – matt

1

Xem Random.Next(minValue, maxValue)

thông số

MINVALUE Loại: System.Int32 thấp Các bao gồm ràng buộc của số ngẫu nhiên trở lại.

maxValue Loại: System.Int32 Giới hạn trên riêng biệt của số ngẫu nhiên được trả lại. maxValue phải lớn hơn hoặc bằng minValue.

1

Để thêm vào câu trả lời của Marc, bạn cũng có thể sử dụng Random.Next(Int32) từ thấp ràng buộc của bạn là 0, vì vậy nó sẽ chỉ đơn giản là:

rand.Next(3) 
Các vấn đề liên quan