首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >蒙蒂霍尔程序模拟(C#)

蒙蒂霍尔程序模拟(C#)
EN

Stack Overflow用户
提问于 2013-04-25 19:46:03
回答 3查看 1.9K关注 0票数 7

我正在尝试用我最熟悉的编程语言C#来模拟Monty Hall Problem (因为我从Think Statistics一书中读到,有个人是在看到计算机模拟后才被说服的)。我的场景是奖品的位置是随机的(在每次运行中),我的选择是随机的,游戏主机对开门的选择是随机的(如果我选择了非奖品,就不能是随机的)。

然而,令人惊讶的是,我的程序实现了50:50的获胜机会,无论我是否切换。下面是它的代码(请原谅我的冗长):

代码语言:javascript
复制
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;
}

这完全是为了我自己的利益,我写它的方式对我来说是最熟悉和舒适的。请随时提出你自己的意见和批评,非常感谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-25 20:02:36

代码语言:javascript
复制
rand.Next(0,2)

仅返回0或1;上限是独占的。你永远不会选择第三扇门(除非你切换),第三扇门永远不会有奖品。你模拟的问题是错误的。

相反,尝试:

代码语言:javascript
复制
rand.Next(0,3)

同样:

代码语言:javascript
复制
int randomlyDisplayedDoor = rand.Next(0, 1);

仅选择第一个候选门;应为:

代码语言:javascript
复制
int randomlyDisplayedDoor = rand.Next(0, 2);

现在我们得到:

代码语言:javascript
复制
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

票数 6
EN

Stack Overflow用户

发布于 2013-04-25 20:05:29

请参阅Random.Next(minValue, maxValue)

参数

minValue类型: System.Int32返回的随机数的包含下界。

maxValue类型: System.Int32随机数返回的排他性上限。maxValue必须大于或等于minValue。

票数 1
EN

Stack Overflow用户

发布于 2014-06-04 20:58:05

为了补充Marc的答案,你也可以使用Random.Next(Int32),因为你的下限是0,所以它应该是简单的:

代码语言:javascript
复制
rand.Next(3)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16213882

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档