“三门问题”的理解和C语言验证

简介 

三门问题——亦称为蒙提霍尔问题,出自美国的电视游戏节目Let’s Make a Deal。问题的名字来自该节目的主持人蒙提·霍尔(Monty Hall)。

游戏规则

  1. 有三扇关闭了的门,其中一扇的背后有辆汽车,另外两扇门背后各有一只羊。
  2. 玩家需要从中选择一扇门,就可以获得门背后的奖品。
  3. 当玩家选定了一扇门,但未打开的时候,主持人知道每扇门后面有什么,会打开另一扇没有汽车的门。
  4. 接下来玩家会被问到:是保持他的原来选择,还是改变决策,选择另一扇仍然关上的门?

那么问题来了,换另一扇门会否增加赢得汽车的概率? 

通过画决策树可知,假设玩家不改变决策的中奖概率为1/3。假设玩家改变决策,中奖概率为2/3

 

“三门问题”的理解和C语言验证

 

“三门问题”的理解和C语言验证

 

直观的理解

不改变决策,相当于三选一。改变决策,相当于三选二。

C语言验证 

用C语言写了一个小程序,模拟实验10000次,验证改变决策后的中奖率为2/3:

//三门问题,模拟玩家改变决策后的中奖率 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 10000      //模拟实验次数
int main()
{
    bool doors[3];   //ture表示门背后是汽车,false表示门背后是羊
    int win=0;       //中奖次数
    int temp;
    srand((unsigned)time(NULL));
    for(int i=0;i<N;i++)
    {
        doors[0]=false;doors[1]=false;doors[2]=false;
        doors[rand()%3]=true;
        int choice = rand()%3;  //随机选择其中一扇门
        if(doors[choice])       //如果玩家打开的门背后是汽车,主持人随机打开另外两扇门中的一扇门 
        {
            int m=rand()%2+1;   //产生1~2随机数
            temp = (choice+m)%3; //temp为玩家改变决策后打开的门的编号
        }
        else       //如果玩家打开的门背后是羊,主持人打开另一扇背后是羊的门 
        {
            if( doors[(choice+1)%3] )
                temp=(choice+1)%3;
            else
                temp=(choice+2)%3;
        }
        if(doors[temp])
            ++win;  
    }
    float ratio = win/(float)N;
    printf("%f\n",ratio);
    //输出结果为0.663900,约等于2/3
    return 0;
}