看到一段关于“三门问题”的视频,第一感觉就是视频的结论有误。本想一笑了之,但看了评论,迷惑了:三门问题的答案到底是什么?

作为勤学好问的码农,不知道最终答案,还是很难受的,于是深入研究一下,发现”小丑竟然是自己“。如果你想挑战一下自己,可以先跳过推理和结论部分,自己先得出一个答案,然后再看看是否正确。

一条朋友圈

在花了一个小时,弄懂三门问题之后,发了一条这样的朋友圈:

三门问题:有三扇门,其中一扇后面是汽车,另外两扇是山羊。当你选择一扇门后,主持人从另外两扇门中打开一扇有山羊的。那么,此时换门是否会增加获得汽车的概率?

第一次错:直觉,换与不换都是1/2的概率;差点止步于此,得出结论:都是骗人的。

第二次错:列举,(选1,去2,换)、(选2,去1,换)、(选3,去1,不换)、(选3、去2、不换),看似概率依旧是1/2。但这里犯了一个错误,没引入首选的概率,也就是后两种情况不能按1/4算,只能按1/6算。

第三次引入概率:1/3(选1,去2,换)、1/3(选2,去1,换)、1/6(1/3 * 1/2)(选3,去1,不换)、1/6(1/3 * 1/2)(选3、去2、不换),后两项合计只有1/3概率。

所以,三门问题的答案是:选择换。概率会从原来的1/3,变成2/3;

通过这个问题在想:有时候,坚持可能是错的,可能是主观判断,可能环境已经发生了变化;但有时候又要坚持,要坚持对答案的怀疑,不断寻找答案。

如果从底层逻辑来说就是:坚持动态的看待问题。也就是:士别三日当刮目相待。

发完这条朋友圈,感觉这个问题有必要通过程序实现一下,同时写篇文章分享出来,于是就有了这篇文章。

如果上面的分析没看懂,也没关系,下面就结合代码再分析实践一下。

三门问题

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

问题场景:

参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,选中后面有车的那扇门可赢得该汽车,另外两扇门后面则各藏有一只山羊。当参赛者选定了一扇门,但未去开启它的时候,节目主持人开启剩下两扇门的其中一扇,露出其中一只山羊。主持人其后会问参赛者要不要换另一扇仍然关上的门。问题是:换另一扇门是否会增加参赛者赢得汽车的机率。

据说,90%的人都选择了不换。你的选择是什么呢?

概率分析

先看下图,存在汽车、山羊1、山羊2,三个门:

选手选择三个门的概率都是三分之一,下面进行具体的假设:

  • 假设选手选择了山羊1,那么主持人打的门只能是山羊2,因为有汽车的门是不能打开的。这种情况发生的概率为:1/3(选手选择山羊1的概率)* 1(主持人的选择是确定的) = 1/3;此时如果,则赢得汽车;
  • 假设选手选择了山羊2,那么主持人打的门只能是山羊1,因为有汽车的门是不能打开的。这种情况发生的概率为:1/3(选手选择山羊2的概率)* 1(主持人的选择是确定的) = 1/3;此时如果,则赢得汽车;
  • 假设选手选择了汽车,那么主持人有两种打开选择:山羊1和山羊2。主持人选择山羊1的概率:1/3(选手选择汽车的概率)* 1/2(主持人二选一) = 1/6;主持人选择山羊2的概率:1/3(选手选择汽车的概率)* 1/2(主持人二选一) = 1/6;所以,当选手选择了汽车的门时,发生的概率为:1/3 * 1/2 + 1/3 * 1/2 = 1/3。此时如果不换,则赢得汽车;

很显然,三种情况发生的概率都为三分之一,换之后赢得汽车的概率是不换的2倍。也就是说:换之后,赢得汽车的概率变成了2/3。

程序演示

上面做了理论分析,下面写一段代码,来验证一下:

public class ThreeDoors {/*** 随机选择器*/private static final Random RANDOM = new Random();/*** 成功总次数*/private static int SUCCESS_COUNT = 0;/*** 重复执行10w次*/private static final int PLAY_TIMES = 100000;public static void main(String[] args) {// 执行游戏10w次for (int i = 0; i < PLAY_TIMES; i++) {playGame();}// 计算选择"换"的概率BigDecimal yield = new BigDecimal(SUCCESS_COUNT).divide(new BigDecimal(PLAY_TIMES), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));System.out.println("执行" + PLAY_TIMES + "次实验,选择【交换】的概率为:" + yield + "%");}public static void playGame() {// 初始化三扇门,默认为false,都没有车boolean door1 = false, door2 = false, door3 = false;// 选手选择的门是否为汽车,true:是boolean pickedDoor;// 最后剩下的门是否为汽车,true:是boolean leftDoor;// 第一步:随机选择一扇门,放入汽车switch (pickDoor(3)) {case 1:door1 = true;break;case 2:door2 = true;break;case 3:door3 = true;break;default:System.out.println("异常数值");break;}// 第二步:选手选择一扇门,依旧采用上面选门的算法int playerPickedDoor = pickDoor(3);// 第三步:主持人移除一扇有山羊的门// 其中主持人只能二选一,移除1一扇门,相当于选择了另一扇门if (playerPickedDoor == 1) {// 选手选择门1pickedDoor = door1;// 如果门2有车,则只能移除门3if (door2) {leftDoor = door2;} else if (door3) {// 如果门3有车,则只能移除门2leftDoor = door3;} else {// 两个门都没车,随机二选一if (pickDoor(2) == 1) {leftDoor = door2;} else {leftDoor = door3;}}} else if (playerPickedDoor == 2) {// 选手选择门2pickedDoor = door2;// 如果门1有车,则只能移除门3if (door1) {leftDoor = door1;} else if (door3) {// 如果门3有车,则只能移除门1leftDoor = door3;} else {// 两个门都没车,随机二选一if (pickDoor(2) == 1) {leftDoor = door1;} else {leftDoor = door3;}}} else {// 选手选择门3pickedDoor = door3;// 如果门1有车,则只能移除门2if (door1) {leftDoor = door1;} else if (door2) {// 如果门2有车,则只能移除门1leftDoor = door2;} else {// 两个门都没车,随机二选一if (pickDoor(2) == 1) {leftDoor = door1;} else {leftDoor = door2;}}}// 第四步:上述结果一定的情况,选手选择更换门pickedDoor = leftDoor;// 第五步:判断该门是否有车if (pickedDoor) {SUCCESS_COUNT++;}}/*** 随机选择一个门*/public static int pickDoor(int bound) {return RANDOM.nextInt(bound) + 1;}
}

上述实现方法,暂且未考虑算法优化,只是简单情况判断处理。

上述实现分以下几步:

  • 第一步:随机选择一扇门,放入汽车,这里采用Random随机数,如果对应的门后为车,则对应的值设置为true;
  • 第二步:选手选择一扇门,算法依旧采用Random随机数;
  • 第三步:在选手选择一扇门的前提下,主持人移除一扇没有汽车的门。这里并未处理移除的门,而是记录了移除之后剩下的那扇门的值。如果两扇门都没有车,则随机二选一。
  • 第四步:选手选择交换,即选手选择的门变成了剩下的那扇门。
  • 第五步:开门,验证,如果成功记录一次;
  • 第六步:执行10w次之后,计算百分比;

最终打印日志如下:

执行100000次实验,选择【交换】的概率为:66.7500%

多执行几次,会发现几乎都在66%-67%之间,说明选择【换】,的确可以让成功的概率翻倍。

小结

最后,回顾一下整个过程:无意看到一条讲”三门问题“的视频,先是做出了直观判断(错误的),对别人的结论嗤之以鼻,然后发现许、异议。于是,开始寻求佐证,最终得到了正确的答案。

正像在朋友圈中说的:有时候,坚持可能是错的,可能是因为主观判断,也可能是因为环境已经发生了变化;但有时候又要坚持,要坚持对答案的怀疑,对答案的不断追寻。

这也应该是我们做事的底层逻辑,不能单靠【感觉】来判断,更多的要采用事实作为依据。特别是程序员,我们还可以用程序来解决类似的问题。

同时,你是否发现,用程序来解决生活中的一些问题,不也是很有意思的吗?

博主简介:《SpringBoot技术内幕》技术图书作者,酷爱钻研技术,写技术干货文章。

公众号:「程序新视界」,博主的公众号,欢迎关注~

技术交流:请联系博主微信号:zhuan2quan


程序新视界”,一个100%技术干货的公众号

弄懂“三门问题”,成功概率翻倍,来用代码验证一下相关推荐

  1. python处理速度_如何让Python处理速度翻倍?内含代码

    原标题:如何让Python处理速度翻倍?内含代码 作为在日常开发生产中非常实用的语言,有必要掌握一些python用法,比如爬虫.网络请求等场景,很是实用.但python是单线程的,如何提高python ...

  2. 如何让 python 处理速度翻倍?内含代码

    阿里妹导读:作为在日常开发生产中非常实用的语言,有必要掌握一些python用法,比如爬虫.网络请求等场景,很是实用.但python是单线程的,如何提高python的处理速度,是一个很重要的问题,这个问 ...

  3. python 多线程和协程结合_如何让 python 处理速度翻倍?内含代码

    阿里妹导读:作为在日常开发生产中非常实用的语言,有必要掌握一些python用法,比如爬虫.网络请求等场景,很是实用.但python是单线程的,如何提高python的处理速度,是一个很重要的问题,这个问 ...

  4. laravel increment出现了翻倍递增_中国股市:如何判断“强庄股”的出现,看懂主力心甘情愿送钱上门...

    什么是强庄股? 强庄股是指有强势庄家操纵的股票.但强庄股在不同的市场环境下,其定义不同. 在强势市场环境下,涨幅翻倍的股票属于强庄股. 在弱势市场环境下,涨幅超过同期大盘走势的股票属强庄股. 有过一波 ...

  5. 前谷歌董事长施密特:美国AI领导地位岌岌可危,科研预算投入得翻倍

    还记得前谷歌董事长兼CEO施密特吗? 他自2001年接受谷歌创始人拉里·佩奇和谢尔盖·布林邀请,担任了谷歌长达10年的CEO,经历了谷歌从"创业公司"到IPO上市,最后巨头参天.施 ...

  6. 这一次,终于弄懂了协变和逆变

    一.前言 刘大胖决定向他的师傅灯笼法师请教什么是协变和逆变. 刘大胖:师傅,最近我在学习泛型接口的时候看到了协变和逆变,翻了很多资料,可还是不能完全弄懂. 灯笼法师:阿胖,你不要被这些概念弄混,编译器 ...

  7. 毕业一年多被裁,没有计算机文凭,我在两个月内搞定4份Offer,且收入翻倍

    裁员往往来得猝不及防,被重新丢回求职市场才发现自己还不具备竞争优势,这是很多人近期面临的窘境.但两个月拿到四份数据科学 Offer 的 Emma Ding 告诉我们,只要有针对性地认真准备,逆风翻盘也 ...

  8. 程序员,学会这些技能让你的薪资翻倍!

    话不多说,直接上图更直观! 这是2019年程序员年薪状况图,从图中可以看到程序员的年薪呈正态分布,一半人集中在10-20万之间.年薪在5-10万的程序员占比为13.3%,年薪在20-25万的程序员占比 ...

  9. 年薪翻倍的100篇面经:如何转型AI拿到阿里等大厂的40万offer

    前言 熟悉我的朋友可能已经知道,我个人从 2010 年开始在CSDN写博客,写了十年,如今接近1700万PV,创业做「七月在线」则已五年,五年已30多万学员.这五年经历且看过很多的人和事,比如我们的机 ...

最新文章

  1. 句法分析语料:哈尔滨工业大学SemEval、清华大学树库
  2. 实现手机左右滑屏效果
  3. PMCAFF问答精选 | 产品新手写PRD需要注意什么?
  4. @产品部 -- 腾讯策划部是如何培养用户的《王者荣耀》“瘾”的
  5. SQL 备份还原单个表
  6. linux系统下c语言编程的,Linux操作系统下C语言编程从零开始
  7. C#全能数据库操作类及调用示例
  8. linux设置多语言环境,怎么为Linux系统配置多语言环境?
  9. JavaScript:this是什么?
  10. 【传输文件】文件传输协议FTP、SFTP和SCP
  11. nodejs——qureystring的作用
  12. windows控件常用缩写
  13. java中返回怎样返回,java-如何显示方法是否可以返回nu
  14. 腾讯三面:Cookie的SameSite了解吧,那SameParty呢?
  15. apache OpenNLP简要介绍
  16. 寒假11:寂寞的数、连续正整数的和、学做菜
  17. nyoj-34-韩信点兵
  18. SVN SSL错误解决
  19. 统计学(二)之一般线性模型(一)
  20. docker-compose 启动mysql、mongodb

热门文章

  1. 石墨烯在生物医学上应用的研究进展_石墨烯导电油墨的制备和应用
  2. 搜狗翻译宝Pro再次开挂,智能翻译硬件成中国人工智能的新风口
  3. 微信小程序引入iconfont单色图标实例(Unicode方式)
  4. Java习题练习:和尚挑水
  5. 下载蓝盒插件_推荐几款 Chrome m3u8 播放器插件(附下载)
  6. 1.3T计算机学科视频教程
  7. CSS快速学习(2021.2.7-15)
  8. 新郑计算机培训机构排名前十,新郑美术培训中心排名
  9. 互联网大会蓝皮书_世界互联网大会蓝皮书
  10. navicat的连接