三门问题(Monty Hall problem)的代码模拟

今天偶尔看到有人在讨论三门问题,这个问题有点意思,但稍微有点绕。

三门问题(Monty Hall problem)亦称为蒙提霍尔问题、蒙特霍问题或蒙提霍尔悖论,大致出自美国的电视游戏节目Let‘s Make a Deal。问题名字来自该节目的主持人蒙提·霍尔(Monty Hall)。有三扇关闭的门,其中一扇门后面是汽车,另外两扇门后面各是一只山羊。节目主持人事先知道每扇门后面分别是什么东西(汽车还是山羊)。节目嘉宾可以从三扇门中挑选一扇门,如果选中后面有汽车的那扇门可赢得该汽车。当嘉宾选定了一扇门但未去开启它的时候,节目主持人会打开剩下两扇门中有山羊的那一扇门(如果剩下的两扇门都是山羊,那么主持人随机从两扇门中挑一扇打开)。主持人在打开有山羊的一扇门后,会问嘉宾要不要改为选择另一扇仍然关着的门。问题是:换另一扇门是否能增加嘉宾赢得汽车的机率?

周末没事,给出一个C代码的模拟,模拟上面这个“嘉宾先选一扇门、主持人打开一扇门、嘉宾决定是否换门”的操作,模拟次数定义为MAX_TRIES。模拟完后,打印出总次数、嘉宾首次即选中汽车的概率、嘉宾换门之后赢得汽车的概率。

#include "pch.h"#include#include#include

classCRand

{public:

CRand()

{

m_weakRndReady= false;

m_hProv=NULL;if (!CryptAcquireContext(&m_hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))

{

srand(GetTickCount());

m_weakRndReady= true;

}

}~CRand()

{if(m_hProv)

CryptReleaseContext(m_hProv,0);

}

DWORD GenDWORD()

{

DWORD r;if (m_hProv && CryptGenRandom(m_hProv, sizeof(DWORD), (BYTE*)&r))returnr;if (!m_weakRndReady)

{

srand(GetTickCount());

m_weakRndReady= true;

}return rand() *GetTickCount();

}private:

HCRYPTPROV m_hProv;boolm_weakRndReady;

};enum{

GOAT= 0, //山羊

CAR = 0xFF, //汽车

};

constexpr DWORD NUM_DOORS= 3;

DWORD doors[NUM_DOORS];

CRand rnd;

inlinevoidInitDoors()

{

memset(doors, GOAT,sizeof(doors)); //每个门都初始化为山羊

doors[rnd.GenDWORD() % NUM_DOORS] = CAR; //其中随机的一个门初始化为汽车

}const DWORD doorsLeftTable[NUM_DOORS][NUM_DOORS - 1]

{

{1, 2 }, //首次选编号为0的门时,则剩下编号为1、2的门

{ 0, 2 }, //首次选编号为1的门时,则剩下编号为0、2的门

{ 0, 1 } //首次选编号为2的门时,则剩下编号为0、1的门

};

inlinevoid OpenTheDoorWithGoat(const DWORD doorChosen, DWORD &doorOpen, DWORD &doorLeft)

{const DWORD *doorsLeft =doorsLeftTable[doorChosen];

DWORD doorIndex= rnd.GenDWORD() % (NUM_DOORS - 1); //剩下的两个门中先随机选一个

doorOpen =doorsLeft[doorIndex];

doorLeft= doorsLeft[1 -doorIndex];if (doors[doorOpen] == CAR) //随机选中的门里是汽车,则改成不是汽车的那个门

{

DWORD t= doorOpen; //交换

doorOpen =doorLeft;

doorLeft=t;

}

}int main(int argc, char**argv)

{

constexpr DWORD MAX_TRIES= 100000;

DWORD winOnFirst= 0; //首次即选中汽车的次数 = 不更换门时选中汽车的次数

DWORD winOnChange = 0; //更换门之后,选中汽车的次数

for (DWORD k = 0; k < MAX_TRIES; ++k)

{

InitDoors();

DWORD doorChosen= rnd.GenDWORD() % NUM_DOORS; //随机选个门

if (doors[doorChosen] ==CAR)++winOnFirst;

DWORD doorOpen, doorLeft;

OpenTheDoorWithGoat(doorChosen, doorOpen, doorLeft);//打开剩下两个门中有山羊的门

if (doors[doorLeft] ==CAR)

++winOnChange;

}

printf("%u, %.3f%%, %.3f%%", MAX_TRIES, (float)winOnFirst * 100.0 / (float)MAX_TRIES,

(float)winOnChange * 100.0 / (float)MAX_TRIES);return 0;

}

使用Windows Crypto API提供的随机数。可以看到,模拟次数越多,随机数越接近理想状态,这是自然的。

首次选中汽车的概率,加上换门选中汽车的概率,为100%,看起来很巧合。这是因为:

1、首次如果选中了汽车(概率为1/3),那么换门就必然丢掉汽车,换句话说,不换门就必然赢得汽车。这个分支的结论和主持人开两个门中的哪个门完全没关系。

2、首次如果没选中汽车(概率为2/3),那么必须换门才能赢得汽车(这个和主持人开门无关)。而且换门就必然赢得汽车(想想是为什么?因为主持人的开门暴露了剩下的那个没汽车的门才导致的呀!)。

综合1和2,换个方式说:

如果嘉宾采取换门的策略,有2/3的概率赢得汽车;

如果嘉宾采取不换门的策略,有1/3的概率赢得汽车;

如果你是嘉宾,你会选哪种策略?

C:WINDOWSsystem32> C:UsershappysourceeposProject1ReleaseProject1.exe100000000, 33.333%, 66.667%

C:WINDOWSsystem32> C:UsershappysourceeposProject1ReleaseProject1.exe100000000, 33.324%, 66.676%

C:WINDOWSsystem32> C:UsershappysourceeposProject1ReleaseProject1.exe10000000, 33.347%, 66.653%

C:WINDOWSsystem32> C:UsershappysourceeposProject1ReleaseProject1.exe1000000, 33.388%, 66.612%

C:WINDOWSsystem32> C:UsershappysourceeposProject1ReleaseProject1.exe100000, 33.560%, 66.440%

三门问题的计算机模拟,三门问题(Monty Hall problem)的代码模拟相关推荐

  1. 用贝叶斯定理解决三门问题并用Python进行模拟(Bayes' Rule Monty Hall Problem Simulation Python)...

    三门问题(Monty Hall problem)也称为蒙提霍尔问题或蒙提霍尔悖论,出自美国的电视游戏节目<Let's Make a Deal>.问题名字来自该节目的主持人蒙提·霍尔(Mon ...

  2. 用贝叶斯定理解决三门问题并用Python进行模拟(Bayes‘ Rule Monty Hall Problem Simulation Python)

    用贝叶斯定理解决三门问题并用Python进行模拟(Bayes' Rule Monty Hall Problem Simulation Python) 参考文章: (1)用贝叶斯定理解决三门问题并用Py ...

  3. 三门问题(Monty Hall problem)背后的贝叶斯理论

    文章目录 1 前言 2 问题简介 3 直观的解释 4 贝叶斯理论的解释 1 前言 三门问题可以说有着各种版本的解释,但我看了几个版本,觉得没有把其中的条件说清楚,所以还是决定按照自己的理解记录一下这个 ...

  4. 三门问题的计算机模拟,三门问题和 JavaScript 仿真实验

    三门问题和 JavaScript 仿真实验 2017-05-20 by Dron 三门问题 1990 年 9 月美国<广场杂志>的「请教玛丽琳」专栏,曾刊登如下逻辑题: 假设你在进行一个游 ...

  5. 三门问题的计算机模拟,三门问题

    三门问题(Monty Hall problem)亦称为蒙提霍尔问题.蒙特霍问题或蒙提霍尔悖论,大致出自美国的电视游戏节目Let's Make a Deal.问题名字来自该节目的主持人蒙提·霍尔(Mon ...

  6. Monty Hall Problem

    蒙提霍尔三门问题,看到这个问题的描述和答案后.有点不理解,后来看了点其他文章,然后也写了代码验证,弄明白这个问题了. 百度百科上面关于这个问题的描述也是正确的.百度百科对三门问题的解释 Monty H ...

  7. 概率论的学习和整理--番外8:3门问题 (Monty Hall problem)

    1 为什么要专门讨论3门问题 我以前没觉得3门问题有这么重要,但是买了一些老外写的概率书,包括很出名的普林斯顿概率论书上也举这个例子,有的概率论书好像开篇就讨论3门问题 这个可能跟老外,喜欢举例子,喜 ...

  8. 蒙提霍尔问题(The Monty Hall Problem)解析(贝叶斯分析、Python仿真)

    目录 0. 前言 1. 什么是蒙提霍尔问题(Monty Hall problem) 2. Naive approach:分类讨论 3. Python蒙特卡洛仿真 4. 直观的理解1 5. 贝叶斯方法 ...

  9. 有趣的三扇门问题(Monty Hall Problem)

    在刚开始学概率论的时候,估计都接触过三扇门问题,今天我们也来聊聊,其实这个问题特别有趣,故事是这样的: 美国有一个电视游戏节目叫Let's Make a Deal,主持人是蒙提霍尔.他身后有三扇门,其 ...

最新文章

  1. PHP大法——实验吧
  2. 设计模式--中介者(Mediator)模式
  3. 开发基础之使用git把项目提交到github托管
  4. 搭建基于域名的虚拟web主机
  5. Java线程问题问答
  6. oracle同库复制schema,使用impdp复制oracle的schema数据迁移 | 学步园
  7. 寒冬之下,移动开发没人要了, iOS 开发者该 何去何从?
  8. 【react】---组件传值的介绍
  9. java.util.ArrayList#add探索
  10. java匿名类 - new接口
  11. OpenCV-图像处理(19、Canny边缘检测)
  12. 深入理解Linux网络技术内幕学习笔记第二章:一些重要的数据结构
  13. python实践日记二
  14. iOS应用内付费(In-App Purchase,IAP,内购)实现要点总结
  15. oracle里的ols机制,[Oracle] 数据库安全之 - Oracle标签安全(OLS)
  16. 网络安全学习笔记——DNS漏洞
  17. cacheable 表达式_Spring Boot缓存注解@Cacheable、@CacheEvict、@CachePut使用
  18. 为什么很多公司都在招测试开发?
  19. 网络爬虫playwright实现网站自动登录并签到
  20. Mongodb 3.6安装过程(centos7.9)

热门文章

  1. 信号量与生产者消费者问题
  2. 看懂IPv6+,这篇就够了
  3. Linux MySQL数据库冷迁移采坑记录
  4. 计算机话筒技术指标,手把手教你搞懂麦克风的技术指标
  5. 运维演进正确之道_API演进的正确方法
  6. 全球及中国线性电位器行业研究及十四五规划分析报告
  7. 鸿蒙开发之表格布局(TableLayout)
  8. 叩响秋雨梧桐的大门——2018中考之后
  9. geogebra与matlab,浅谈Geogebra在大学数学教学中的应用
  10. 华为云 两个手机 同步_HDC.Cloud | 技术探秘:华为云鲲鹏云手机何以公有云业界独家...