【问题标题】:Monty Hall Problem C Monte Carlo Simulation蒙蒂霍尔问题 C 蒙特卡罗模拟
【发布时间】:2020-03-22 00:00:17
【问题描述】:

所以在看了另一个关于蒙蒂霍尔问题的视频后,并且因为我了解了蒙特卡洛模拟方法,我想如果你换门,我会尝试找到 66.66% 的游戏获胜百分比。问题是我得到了 50%,而在考虑算法时担心的一件事是我的模型是否正确。我实施了 2 个随机猜测,一个用于选择 1 到 3 的门,有 3 分之一的机会,一个用于选择切换门,有 2 分之一的机会。 if 语句用于分配具有奖品的门以及每种猜测的不同可能性。我不知道我是否可以减少那部分,但它现在有效(我认为)。我的想法哪里不对?你能建议我的算法修复吗?非常感谢!

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
int main()
{
    int seed=time(NULL);
    srand(seed);
    double u, random[2], suitch=0.0, total=0.0;
    int nall=10000000, nright=0, i, door[3], k, j;
    for(j=0; j<nall; j++)
    {
        for(i=0; i<3; i++)
            random[i]=0.0, door[i]=0;
        for(i=0; i<2; i++)
        {
          u=(1.*rand())/RAND_MAX;
            random[i]=3.*u;
            //printf("%lf\t%lf\n",u,random[i]);
        }
        suitch=2.*u;
        //printf("%lf\n",suitch);
        if(floor(random[0])==0)
            door[0]=1, door[1]=0, door[2]=0;
        else if(floor(random[0])==1)
            door[0]=0, door[1]=1, door[2]=0;
        else if(floor(random[0])==2)
            door[0]=0, door[1]=0, door[2]=1;
        for(i=0; i<3; i++)
            //printf("%d\t",door[i]);
        if((floor(random[1])==0)&&(floor(suitch)==0))
            k=door[0];
        else if((floor(random[1])==1)&&(floor(suitch)==0))
            k=door[1];
        else if((floor(random[1])==2)&&(floor(suitch)==0))
            k=door[2];
        else if((floor(random[1])==0)&&(floor(suitch)==1))
            {
                if(door[1]==1)
                k=door[1];
            else if(door[1]==0)
                k=door[2];
            }
        else if((floor(random[1])==1)&&(floor(suitch)==1))
            {
                if(door[0]==1)
                    k=door[0];
                else if(door[0]==0)
                    k=door[2];
            }
        else if((floor(random[1])==2)&&(floor(suitch)==1))
            {
                if(door[0]==1)
                    k=door[0];
                else if(door[0]==0)
                    k=door[1];
            }
        if(k==1)
            nright++;
    }
    total=1.*nright/nall;
    printf("%d\t%d\t%lf\t", k, nright, total);
    return 0;   
}

【问题讨论】:

  • 乍一看,我的想法是,您是否考虑过使用变量和函数名称以便了解发生了什么?如果你真的想过火,也许可以在评论中描述基本问题。
  • 随机访问超出范围。
  • 我猜 random[2] 代表奖品在哪里。您错误地将奖品的位置建模为四处移动。它从不移动。 (在我发布答案之前,我问这是否是 random 所代表的 - 需要澄清。)
  • 我的编程知识非常基础和简单,足以解决物理和数学问题。我不知道 c 语言能做什么。只是提醒一下,所以人们不会说“你为什么不那样做,使用那个,添加那个等等”。我只是想梳理一下算法的逻辑。
  • Random[2] 选择是否要切换(floor(random[2])=0->no switch, floor(random[2])=1->switch)。 Door[3] 是奖品(1=赢,0=输)。

标签: c simulation simulator montecarlo


【解决方案1】:

我查看您的代码太久了,看不出问题所在。我真是个白痴,哈哈。代码没有问题(除了意外的,幸运的是,内存溢出是良性的)。问题是您要模拟什么。

您模拟了 10000000 场游戏,其中一半的情况下玩家决定守门(在这种情况下他的机会是 33.3%),而在一半的情况下玩家决定切换(在这种情况下他的机会是 66.7%)案子)。当然你得到了 50%,因为这就是你在模拟的。

永久设置suitch = 1,您将...获得66.7%

是的...请使随机 3 个元素变长或在开始时停止初始化以修复内存溢出,并注释掉以前的调试 for(i=0; i&lt;3; i++),因为您每次迭代运行模拟 ifs 链 3 次,没有好理由。但这无关紧要:-)

【讨论】:

  • 首先,我为我的代码太糟糕而且难以理解除了我之外的任何东西做了什么表示歉意。昨晚睡觉时,我正在思考如何通过提出游戏中可能发生的所有可能场景来更好地理解蒙蒂霍尔问题。然后我发现了代码逻辑的问题。我的代码算作赢得了两种策略,切换和不切换。因此,如果您不在乎使用什么策略,实际结果是 50% 的胜率。当我去掉no switch部分或者使用suitch=1时,我得到了66.6%。顺便说一下没有内存溢出。
  • @NegafilmsOrigins:理解蒙蒂霍尔问题的一个非常简单的方法是:想象一下 3000 张桌子,每张桌子有 1 张红卡和 2 张黑卡,正面朝下。你的 3000 个克隆人随机将手指放在一张卡片上。偶然地,在大约 1000 张牌桌中,您的克隆人手握红牌。在每张桌子上,展示一张既没有手指也不是红色的牌。你的克隆人在多少张牌桌上有过红牌?还是1000,因为他们没有动手指。因此,留在第一选择有1/3的获胜概率。所以切换的概率一定是 2/3。
  • 我的想法是:如果1赢0输,100代表1门赢,2门3输,那么我们有3个版本,100,010,001 . 如果您每次都选择一个特定的门,例如门 1,那么您有 1/3 的获胜机会而无需切换。但如果你切换,你有 2/3 的机会选择错误的门,并且主人揭示了另一扇错误的门,你自动获胜。
  • Beliebe Boris,我模拟了游戏 1000000000 次,赢得了 6.66 亿辆汽车。现在我正在花钱寻找一个可以停放它们的地方。
  • @LuisColorado 作为奖励,您现在应该有足够的山羊来养活整个星球。或者......用山羊屁过热。
猜你喜欢
  • 2018-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 2013-01-02
  • 2012-04-26
相关资源
最近更新 更多