0

So after seeing another video for the Monty Hall Problem and since I learned about Monte Carlo simulation methods, I thought I would try to find the percentage 66,66% of winning the game if you switch doors. The problem is that I get 50%, and one thing that worried when thinking up the algorithm is if my model was correct. I had 2 random guesses implemented, one for choosing door 1 to 3 with 1 in 3 chances and one for choosing to switch doors with 1 in 2 chances. The if statements were for assigning the doors with the prizes and for the different possibilities for each of those guesses. I don't know if I can reduce that part, but it works for now (I think). Where was my thinking incorrect? And can you suggest a fix to my algorithm? Thank you very much!

#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
    At first glance, my thought is, have you considered using variable and function names so you can tell what's going on? Maybe describe the basic problem in a comment if you want to really go overboard. – Kenny Ostrom Mar 22 '20 at 00:03
  • random is accessed out of range. – Kenny Ostrom Mar 22 '20 at 00:06
  • I'm guessing that random[2] is representing where the prize is. You incorrectly model the prize's location as moving around. It never moves. (I'm asking if that's what random represents here, before I post an answer though -- needs clarification.) – Kenny Ostrom Mar 22 '20 at 00:10
  • My knowledge of programming is very basic and simple enough to solve physics and math problems. I don't know everything c language can do. Just a heads up, so people don't say "why didn't you do it that way, used that, add that, etc". I just want to sort out the logic of the algorithm. – Negafilms Origins Mar 22 '20 at 00:11
  • Random[2] chooses if you want to switch or not (floor(random[2])=0->no switch, floor(random[2])=1->switch). Door[3] are the prizes (1=win, 0=loss). – Negafilms Origins Mar 22 '20 at 00:14
  • The opening of the wrong door is done with the last 3 if statements. Firstly, a door is chosen and the choice to switch is decided, then it looks one of the closed doors, if it's a prize, the wrong door is discarded when it wins if you switch. If it has no prize, it chooses the remaining door. – Negafilms Origins Mar 22 '20 at 00:22
  • The `suitch` probability uses the same random number as `random[1]`, which makes the two numbers related, invalidating the simulation. – 1201ProgramAlarm Mar 22 '20 at 00:37
  • It might be easier if you generating random numbers like https://stackoverflow.com/questions/5008804/generating-random-integer-from-a-range – Kenny Ostrom Mar 22 '20 at 00:49
  • `(1.*rand())/(RAND_MAX)` is wrong. Sometimes `rand()` returns `RAND_MAX`, so it will produce 1 when only values strictly less than 1 are desired. – Eric Postpischil Mar 22 '20 at 11:44
  • `suitch=2.*u;` is wrong. `u` has not been changed since it was used to set `random[1]`, so `suitch` is not independent of `random[1]`. This sets suitch to 0 of `random[1]` is 0, to 0 or 1 each about half the time `random[1]` is 1, and to 1 almost every time (due to the `RAND_MAX` issue above) `random[1]` is 2. That may not affect the average probability though, as the cases are symmetric between the values of `random[1]`. – Eric Postpischil Mar 22 '20 at 11:45
  • I know that my variables are not independent and one influences the other, but it saves space and time trying to write a different way of producing random numbers. I could have written a function and call upon it every time I need to produce a random number, but that is the way I thought to do it at the time I was writing the code. And you are right to say that a random number such as 1 can cause problems for the algorithm, but the chances are super low in my opinion and it doesn't affect 10^8 repetitions. Also, that was something for me to have some fun, so I don't care about that for now. – Negafilms Origins Mar 22 '20 at 13:31

1 Answers1

2

I've been looking at your code way too long, unable to see the problem. What an idiot i've been, lol. There is no problem with the code (except for an accidental, and luckily benign, memory overrun). The problem is what are you trying to simulate.

You simulate 10000000 games, where in half of the cases the player decides to keep his door (his chance is 33.3% in this case) and half of the cases where the player decides to switch (his chance is 66.7% in this case). Of course you are getting 50%, cause thats what you are simulating.

Set suitch = 1, permanently, and you'll... get 66.7%

And yea... please make random 3 elements long or stop initing at the beginning to fix the memory overrun, and comment out the former debug for(i=0; i<3; i++), cause you are running the simulation ifs chain 3 times each iteration for no good reason. But thats unrelated :-)

Boris Lipschitz
  • 1,514
  • 8
  • 12
  • Firstly, I apologize for my code being too awful and difficult to understand what anything does but me. When I went to bed last night, I was thinking about how to better understand the Monty Hall Problem by coming up with all the possible scenarios that can happen in the game. Then I figured out the problem with the logic of the code. My code counts as wins both strategies, switching and no switching. So the actual outcome with be 50% win percentage if you don't care what strategy you use. When I removed the no switch part or used suitch=1, I got 66,6%.There is no memory overrun by the way. – Negafilms Origins Mar 22 '20 at 11:23
  • @NegafilmsOrigins: A very easy way to understand the Monty Hall Problem is: Imagine 3000 tables each with 1 red card and 2 black cards, facedown. 3000 of your clones put their finger on a card, at random. By chance, at about 1000 tables, your clones have fingers on red cards. At each table, reveal a card that neither has a finger on it nor is red. At how many tables do your clones have their fingers on red cards? Still 1000, because they did not move their fingers. Therefore, staying with the first choice has a probability of 1/3 of winning. So switching must have a probability of 2/3. – Eric Postpischil Mar 22 '20 at 12:03
  • The way I think about it is : If 1 is a win and 0 is a loss and 100 means door 1 win and door 2 and 3 losses, then we have 3 versions, 100, 010, 001. If you pick every time one specific door, for example door 1, you have 1/3 chances of winning with no switching. But if you switch, you have 2/3 chances of choosing the wrong door and by the host revealing the other wrong door, you automatically win. – Negafilms Origins Mar 22 '20 at 13:24
  • Beliebe Boris, I simulated the game 1000000000 times and I won 666 million cars. And now I'm spending money looking for a place to park them all. – Luis Colorado Mar 27 '20 at 16:48
  • @LuisColorado as a bonus, you should have enough goats now to feed the entire planet. Or... overheat it with goats farts. – Boris Lipschitz Mar 27 '20 at 16:50