三门问题详解(附C语言实现)

三门问题详解(附C语言实现)三门问题 违背直觉的概率现象 nbsp nbsp 三门问题 MontyHallpro 亦称为蒙提霍尔问题 蒙特霍问题或蒙提霍尔悖论 大致出自美国的电视游戏节目 Let sMakeaDeal 问题名字来自该节目的主持人蒙提 霍尔 MontyHall 参赛者会看见三扇关闭了的门 其中一扇的后面有一辆汽车 选中后面有车的那扇门可赢得该汽车 另外两扇门后面则各藏有一只山羊 当参赛者选定了一扇门 但未去开启它的时候 节目主持人开启剩下两扇门的其中一扇 露出其中一只山羊 主持人其后会问参赛者要

三门问题——违背直觉的概率现象

  1. 第一种方法是从概率合并的角度,最容易理解也最直观,在游戏开始之初,A、B、C三扇门的背后有汽车的概率分别为三分之一,那么A门+B门背后有汽车的概率将会是三分之二,而主持人打开B门之后,A门+B门背后汽车的概率为三分之二的这个事实并不会发生改变,那么这就意味着,此时A门背后有汽车的概率已经从最初的三分之一上升到三分之二。主持人打开空门的操作将换门的选项从两个减少到一个,所以概率也随之上升了,所以当然应该改变选择。考虑一种极端的情况,即10000扇门的情况下,换门的成功率将提升至9999/10000。
  2. 第二种方法则是老老实实的列表计算,该方法最简单,只需列举各种情况再计算相应概率即可。
    在这里插入图片描述
      直白地讲,就是把第一次选择和第二次选择的所有情况进行细化,分析出每一种情况下的条件概率,再把这些概率进行加总,得到了最终的结果:




      用图解的方式也可以更直观地进行理解:在这里插入图片描述

  3. 第三种方法则是通过贝叶斯公式,即
    加粗样式
    也可以很简单地解决这个问题,但是得明确里面的事件A和事件B是代指什么。
      我们用事件A代表你第一次选择的门后是汽车,B代表主持人翻开的门后是山羊。那么已知B的情况下,A发生的条件概率 P{A|B} 显然,第一次选对的概率,即 P{A}=1/3,无需赘述。但是由于不知道主持人的行为,所以无法计算 P{B|A} 和P{B}。
      那么我们具体分析:因为主持人知道门后对应的东西,所以只选择开启有羊的门,于是主持人一定选择山羊,事件 B 一定发生:P{B|A} = 1 主持人一定选择山羊,事件 B 一定发生:P{B} = 1,那么 P{A|B} = 1/3,所以不换的胜率是1/3,因此一定要换。








#define _CRT_SECURE_NO_WARNINGS #include  
     #include  
     #include  
     #include  
     #include  
     #include 
     #include 
     static const int testCount = 10000; static int findSwap(int *p, int n, int choose); int main() { 
    int n; printf("请输入门数\n"); scanf("%d", &n); while (n < 1) { 
    printf("请重新输入门数\n"); scanf("%d", &n); } int *p = (int *)malloc(sizeof(int)*n); int swapSuccess = 0; int nonSwapSuccess = 0; srand((unsigned)time(0)); //重复10000次随机试验 for (int i = 0; i < testCount; i++) { 
    //有汽车的那扇门 int car = 1 + rand() % n; //printf("汽车在第%d 扇门\n",car); for (int i = 0; i < n; i++) { 
    *(p + i) = 0; } //参赛者选择的门 int choose = 1 + rand() % n; //printf("参赛者选择第%d 扇门\n", choose); int count = 0; for (int i = 1; i <= n; i++) { 
    if (i != choose && i != car) { 
    //printf("打开第%d 扇门\n", i); *(p + i - 1) = 1; count++; } if (count == n - 2) { 
    break; } } int swap = findSwap(p, n, choose); //printf("剩下第%d 扇门,是否交换?\n", swap); //swap == car ? printf("交换成功\n") : printf("交换失败\n"); swap == car ? swapSuccess++ : nonSwapSuccess++; } printf("交换的成功次数为%d 不交换的成功次数为%d\n", swapSuccess, nonSwapSuccess); printf("交换成功率为%4.2f\n", swapSuccess*1.0 / testCount); system("pause"); } //选择是否交换的门 static int findSwap(int *p,int n,int choose) { 
    for (int i = 1; i <= n; i++) { 
    if (*(p + i-1)==0 && (i!=choose) ) { 
    return i; } } return -1; } 
  1. https://blog.csdn.net/bjweimengshu/article/details/
  2. https://baijiahao.baidu.com/s?id=&wfr=spider&for=pc
  3. https://www.jianshu.com/p/b1fbc0?from=groupmessage
  4. https://www.zhihu.com/question/
  5. https://www.bilibili.com/video/BV1ws411j7Mb?from=search&seid=
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/204354.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午8:29
下一篇 2026年3月19日 下午8:29


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号