蒙蒂霍尔程序仿真(c#)
本文关键字:仿真 程序 | 更新日期: 2023-09-27 18:10:55
我正在尝试用c#(我最熟悉的编程语言)模拟Monty Hall问题(因为我从Think Statistics这本书中读到,有一个人只有在看到计算机模拟后才被说服)。我的场景是这样的,奖品的位置是随机的(在每次运行中),我的选择是随机的,游戏主持人打开门的选择是随机的(如果我选择了非奖品,它就不可能是随机的)。
令人惊讶的是,我的程序达到了50:50的获胜机会,无论我是否切换。下面是它的代码(请原谅我的冗长):
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;
}
这完全是为了我自己的兴趣,我用我最熟悉和最舒服的方式来写它。请随时提出自己的意见和批评,非常感谢!
rand.Next(0,2)
只返回0或1;上界是不相容的。你永远不会选择第三扇门(除非你换了),而第三扇门永远不会有奖品。你在模拟错误的问题。
试试相反:
rand.Next(0,3)
同样:
int randomlyDisplayedDoor = rand.Next(0, 1);
只选择第一个候选门;应该是:
int randomlyDisplayedDoor = rand.Next(0, 2);
现在我们得到:
If you don't switch, you will win 3320 out of 1000 games.
If you switch, you will win 6639 out of 1000 games.
注意-当等于时,上界是包括 -即rand.Next(1,1)
总是返回1
。
参见随机。Next (minValue, maxValue)
参数minValue类型:系统。Int32返回的随机数的下界。
maxValue类型:系统。Int32返回的随机数的唯一上界。maxValue必须大于或等于minValue。
要添加到Marc的答案中,您还可以使用Random.Next(Int32),因为您的下界是0,所以它将是简单的:
rand.Next(3)