Проблема Монти Холла C Моделирование Монте-Карло - PullRequest
0 голосов
/ 22 марта 2020

Итак, после просмотра другого видео по проблеме Монти Холла и после того, как я узнал о методах моделирования Монте-Карло, я подумал, что постараюсь найти процент 66,66% выигрыша в игре, если вы поменяете двери. Проблема в том, что я получаю 50%, и одна вещь, которая беспокоит, когда я обдумываю алгоритм, - это правильность моей модели. У меня было реализовано 2 случайных предположения, одно для выбора двери с 1 по 3 с вероятностью 1 к 3, а другое - для выбора двери с вероятностью 1 к 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;   
}

1 Ответ

2 голосов
/ 22 марта 2020

Я слишком долго смотрю на твой код, не в силах увидеть проблему. Какой я идиот, лол. нет проблем с кодом (за исключением случайного и, к счастью, доброкачественного переполнения памяти). Проблема в том, что вы пытаетесь симулировать.

Вы симулируете 10000000 игр, где в половине случаев игрок решает сохранить свою дверь (в этом случае его шанс составляет 33,3%), а в половине случаев игрок решает переключиться (его шанс составляет 66,7% в этом случае). Конечно, вы получаете 50% , потому что это то, что вы имитируете.

Установите suitch = 1 навсегда, и вы ... получите 66,7%

И да ... пожалуйста, сделайте случайные 3 элемента длинными или прекратите запуск в начале, чтобы исправить переполнение памяти, и закомментируйте предыдущую отладку for(i=0; i<3; i++), потому что вы запускаете симуляцию, если цепочки 3 раза каждую итерацию без веской причины. Но это не имеет отношения: -)

...