蒙蒂霍尔问题C蒙特卡洛模拟

问题描述 投票:0回答:2

因此,在观看了有关Monty Hall问题的另一段视频之后,由于我了解了蒙特卡洛模拟方法,所以我想我会尝试在您切换门的情况下找到赢得游戏的百分比66.66%。问题是我得到了50%,而在思考算法时担心的一件事是我的模型是否正确。我进行了2次随机猜测,一次是选择1到3个门,每3个机会中的1个,一次选择是选择2个机会中的1个门。 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;   
}
c simulation simulator montecarlo
2个回答
0
投票
我看您的代码太久了,无法看到问题。我曾经是个白痴,大声笑。代码没有

没问题(意外的,幸运的是,良性的内存溢出除外)。问题是您要模拟什么。

您模拟了10000000场游戏,在一半情况下,玩家决定保留自己的门(在这种情况下,他的机会是33.3%),在一半情况下,玩家决定进行切换(在这种情况下,他的机会是66.7% )。当然您会得到

50%

,这就是您要模拟的内容。永久设置suitch = 1,您将获得...的66.7%

而且是的...请延长3个随机元素或在开始时停止初始化以解决内存溢出问题,并注释掉先前的调试for(i=0; i<3; i++),因为您在每次迭代3次的情况下都运行仿真ifs链原因。但这没关系:-)


-1
投票
蒙蒂·霍尔问题:

让我们看看如果不切换门的可能性是多少。可用的方法并不多,因此我们可以手动绘制所有方法:

Actual Winning Choice: Door Win A A Y A B N A C N B A N B B Y B C N C A N C B N C C Y Probability: 3/9 = 1/3 = 30%

让我们通过自动交换进行相同的模拟。注意:Monty无法移除您选择的门或正确的门。因此,如果您选择错误的门,则只有一次选择蒙太奇的机会。但是,如果您选择了正确的门(首选),则有两种选择(因此我们必须在概率表中用尽所有机会。

这是您的代码模拟问题的方式(请注意,实际数学运算需要在此表中再增加几行)。

Actual Monty Winning Removes Choice1: Door Door Choice2: Win A A B C N A A C B N A B C B Y A C B C Y B A C A Y B B A C N B B C A N B C A C Y C A B A Y C B A B Y C C A B N C C B A N Probability: 6/12 = 1/2 = 50%

因此,我相信您的代码正在模仿上面的概率表。错了请看下面的概率表。

但是让我们显示正确的概率表(摆脱我的否定投票)。因此,问题在于您正在模拟上表。

Actual Monty Winning Removes Choice1: Door Door Choice2: Win A A B C N A A C B N A B C B Y A B C B Y A C B C Y A C B C Y B A C A Y B A C A Y B B A C N B B C A N B A C A Y B A C A Y C A B A Y C A B A Y C B A B Y C B A B Y C C A B N C C B A N

这是您应该模拟的:

Probability: 12/18 = 2/3 = 66%

© www.soinside.com 2019 - 2024. All rights reserved.