三门问题(Monty Hall problem)亦称为蒙提霍尔问题,出自美国的电视游戏节目Let's Make a Deal。

问题名字来自该节目的主持人蒙提·霍尔(Monty Hall)。参赛者会看见三扇关闭的门,其中一扇的

后面有一辆汽车,选中后面有车的那扇门可赢得该汽车,另外两扇门后面则各藏有一只山羊。当参赛者

选定了一扇门,但未开启它的时候,主持人会开启剩下两扇门的其中一扇,露出其中一只山羊。主持人

其后会问参赛者要不要换另一扇仍然关上的门。问题是:换另一扇门是否会增加参赛者赢得汽车的机率?

  先做简单的分析:打开门之前中汽车大奖的概率是1/3,打开一个门之后中奖的概率的是1/2。

如果是从直觉来进行分析和判断,好像没啥区别,可实际情况却不是这样的。换另外一扇没有打开的们,

中奖的概率会提升很多。一个简单的解释是,选到门后为羊的概率是2/3,主持人会打开一扇门后有羊的门,

因此转换后获得汽车的概率为2/3.接下来通过代码来验证这个问题,代码如下

/**

* @Author 一只爱阅读的程序员

* @Description 三门问题测试

* @Date 2023/3/14 10:35

* @Version 1.0

*/

public class ThreeDoorTest {

public static void main(String[] args) {

int gameTimes = 100000;

for (int i = 0; i < 5; i++) {

System.out.println("第【" + (i + 1) + "】次测试--->");

testGame(gameTimes);

}

}

/*

* 游戏测试

*/

public static void testGame(int gameTimes) {

List<Awards> awardsList = null;

int winTotal = 0;

for(int i = 0; i < gameTimes; i++) {

// 第一种选择 不更换选项

awardsList = gameReady();

boolean result = judgeIsWin(awardsList);

if (result) {

winTotal += 1;

}

}

System.out.println("测试【" + gameTimes + "】次,不更换选项的中奖次数为: " + winTotal + " 次");

winTotal = 0;

for(int i = 0; i < gameTimes; i++) {

// 第二种选择 更换选项

awardsList = gameReady();

changeGameChoice(awardsList);

boolean result = judgeIsWin(awardsList);

if (result) {

winTotal += 1;

}

}

System.out.println("测试【" + gameTimes + "】次,更换选项的中奖次数为: " + winTotal + " 次");

}

/*

* 更换游戏选项

*/

public static void changeGameChoice(List<Awards> awardsList) {

for (Awards awards : awardsList) {

if (GlobalConfiguration.IS_CHOICE_N.equals(awards.getIsChoice())

&& GlobalConfiguration.IS_OPEN_N.equals(awards.getIsOpen())) {

// 将未被选中的门设置为选中

awards.setIsChoice(GlobalConfiguration.IS_CHOICE_Y);

continue;

}

if (GlobalConfiguration.IS_CHOICE_Y.equals(awards.getIsChoice())

&& GlobalConfiguration.IS_OPEN_N.equals(awards.getIsOpen())) {

// 将已选中的门设置为未选中

awards.setIsChoice(GlobalConfiguration.IS_CHOICE_N);

continue;

}

}

}

/*

* 判断是否中汽车大奖

*/

public static boolean judgeIsWin(List<Awards> awardsList) {

for (Awards awards : awardsList) {

if (GlobalConfiguration.IS_CHOICE_Y.equals(awards.getIsChoice())

&& GlobalConfiguration.PRIZE_TYPE_CAR.equals(awards.getPrizeType())) {

return true;

}

}

return false;

}

private static Random random = new Random();

/*

* 游戏数据准备

*/

public static List<Awards> gameReady() {

List<Awards> awardsList = new ArrayList<>(3);

// 生成基础数据

for(int i = 0; i < 3; i++) {

Awards awards = new Awards();

awards.setDoorId(i + 1);

awardsList.add(awards);

}

// 随机选定一个奖项设置为汽车

int winId = random.nextInt(3);

awardsList.get(winId).setPrizeType(GlobalConfiguration.PRIZE_TYPE_CAR);

// 参赛者随机选中一个门

int doorId = random.nextInt(3);

awardsList.get(doorId).setIsChoice(GlobalConfiguration.IS_CHOICE_Y);

// 主持人打开未被选中的门,并且门后为羊

for(int i = 0; i < 3; i++) {

Awards awards = awardsList.get(i);

if (GlobalConfiguration.IS_CHOICE_N.equals(awards.getIsChoice())

&& GlobalConfiguration.PRIZE_TYPE_SHEEP.equals(awards.getPrizeType())) {

awards.setIsOpen(GlobalConfiguration.IS_OPEN_Y);

break;

}

}

return awardsList;

}

}

/*

* 奖项

*/

@Data

class Awards {

// 门ID

private int doorId;

// 奖品类型

private String prizeType = GlobalConfiguration.PRIZE_TYPE_SHEEP;

// 是否被选中

private String isChoice = GlobalConfiguration.IS_CHOICE_N;

// 是否被打开

private String isOpen = GlobalConfiguration.IS_OPEN_N;

}

/* 配置类 */

class GlobalConfiguration {

// 奖品类型-汽车

public static final String PRIZE_TYPE_CAR = "CAR";

// 奖品类型-羊

public static final String PRIZE_TYPE_SHEEP = "SHEEP";

// 是否被选中-是

public static final String IS_CHOICE_Y = "Y";

// 是否被选中-否

public static final String IS_CHOICE_N = "N";

// 门是否开启-是

public static final String IS_OPEN_Y = "Y";

// 门是否开启-否

public static final String IS_OPEN_N = "N";

}

然后进行测试,总共测试5轮,测试100次的结果如下

测试1000次的结果如下

测试10000次的结果如下

测试100000次的结果如下

从结果可以看出,测试的次数越大,不更换选项时中汽车的的概率更接近1/3;

当更换选择之后,中汽车的的概率更接近2/3。由此可得出结论,玩三门游戏时,

最好还是换一个门中奖的概率更大。

参考百度百科

https://baike.baidu.com/item/%E4%B8%89%E9%97%A8%E9%97%AE%E9%A2%98/1242689?fr=aladdin

用Java代码验证三门问题的更多相关文章

  1. JAVA代码验证身份证信息

    java验证身份证信息代码 转自:http://www.blogjava.net/xylz/archive/2011/01/05/342330.html import java.util.Calend ...

  2. 使用mongo-java-driver3.0.2.jar和mongodb3.0在java代码中的用户验证4

    以下是使用mongo-java-driver3.0.2.jar和mongodb3.0.4在java代码中的用户验证: ServerAddress sa = new ServerAddress(host ...

  3. mongodb3.0分片及java代码连接操作测试(开启用户验证)

    最近抽时间搭建了一下mongodb简单的分片,整个过程还算是蛮顺利,只不过在用户验证这一块遇到了一些问题,好在最后终于搞定. 一.服务器搭建过程: 1.安装四个mongodb:一个作为config.一 ...

  4. Java代码实现文件添加数字签名、验证数字签名

    Linux下实现加签.验签 1.使用OpenSSL 生成公钥和密钥: #用 OpenSSL, Linux 上自带,常用命令如下: #生成 RSA 私钥(传统格式的) openssl genrsa -o ...

  5. 无需Java代码通过JHipster生成有安全验证的微服务应用

    让我们继续登录到我们的应用程序,并导航到Account>Login菜单项.我们将使用admin/admin作为凭据,缺省情况下,JHipster将自动创建.一切进展顺利.欢迎页面将显示确认登录成 ...

  6. Struts2数据验证与使用Java代码进行数据验证

    Struts2数据验证 使用Java代码进行数据验证 重写ActionSupport的validate()方法 对Action类的中所有请求处理方法都会进行验证! 对Action类的数据属性进行检查, ...

  7. C++与JAVA代码实现CRC-16/MODBUS算法,且与 http://www.ip33.com/crc.html 进行结果验证

    CRC-16/MODBUS的多项式为:x16+x15+x2+1(8005),宽度为16.运算时,首先将一个16位的寄存器预置为11111111 11111111,然后连续把数据帧中的每个字节中的8位与 ...

  8. Serializable详解(1):代码验证Java序列化与反序列化

    说明:本文为Serializable详解(1),最后两段内容在翻译上出现歧义(暂时未翻译),将在后续的Serializable(2)文中补充. 介绍:本文根据JDK英文文档翻译而成,本译文并非完全按照 ...

  9. 对一致性Hash算法,Java代码实现的深入研究

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...

  10. 使用 Google Guava 美化你的 Java 代码

    文章转载自:http://my.oschina.net/leejun2005/blog/172328 目录:[ - ] 1-使用 GOOGLE COLLECTIONS,GUAVA,STATIC IMP ...

随机推荐

  1. 通用CSS命名惯例

    通用的 CSS 命名惯例 在参与规模庞大.历时漫长.且参与人数众多的项目时,要确保每一行代码都像是同一个人编写的:这就要求所有开发者,都遵守相同的代码规范.在先前的文章前端项目开发规范意见,从宏观角度 ...

  2. 西瓜书6.2 matlab的libsvm使用

    因为python的教程没有找到详细的所以就改用matlab了 使用的是matlab r2016a,libsvm3-24,具体的安装配置教程就直接参考谦恭大大的了: https://blog.csdn. ...

  3. windows 10 的VMware workstation Pro突然变成英文界面

    电脑的VMware虚拟机界面是中文版的,后来在捣弄些电脑配置,突然变成英文版界面了. 后面发现原来是区域格式选错了:正确的格式是下图红框

  4. UE5农场项目小功能(1)-砍树

    砍树功能效果的实现 ​ 在UE中想做一个砍树的功能,B站上没找到什么教程,最后在油管上找到个视频并跟着实现了,一共设计到三个蓝图和一个什么也没写的蓝图接口,下面介绍下步骤. 1.角色蓝图的部分 人物这 ...

  5. sqlsever中使用的 select top n在mysql 语句中如何更改

    string sqlSelect = "select top(3) ROW_NUMBER() over(order by UserTime) as Num,* from " + & ...

  6. C++ 函数与数组

    C++ 函数与数组 #include<iostream> using namespace std; const int ArSize = 8; int sum_arr(int arr[], ...

  7. xShell执行js脚本

    var CMD = 'ls'; var INTERVAL = 1; var MAX = 5; var CR = String.fromCharCode(13); var LF = String.fro ...

  8. React中的CSS模块

    CSS模块       使用步骤:         1.新建一个XXX.moudle.css文件         2.在组件中引入css           impor classes(变量) fro ...

  9. 创建vue项目时所发送错误

    该错误的造成可能是以下情况: 1.所需插件可能没有安装齐全: 2.网络不好,更换网络可能会解决: 3.github无法访问,导致无法下载所需模板: (由于github是外网网站,该网站并不是每次访问都 ...

  10. Vivado中综合,实现,编程和调试工程可能会出现的问题及解决方案

    Xilinx公司的IDE(集成开发环境) Vivado用处广泛,学会使用Vivado对FPGA的学习至关重要,这里以PRX100-D开发板为例,对Vivado的学习使用进行探讨.本文将会持续更新,列出 ...