首页 > 编程语言 >用Java代码验证三门问题

用Java代码验证三门问题

时间:2023-03-18 22:13:49浏览次数:43  
标签:Java 验证 int awardsList GlobalConfiguration 三门 awards static public

  三门问题(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,验证,int,awardsList,GlobalConfiguration,三门,awards,static,public
From: https://www.cnblogs.com/yilangcode/p/17231954.html

相关文章

  • JavaScript 数据类型详解
    原文链接:​   ​​https://note.noxussj.top/?source=51cto​​常见的ES5数据类型分为基本数据类型、引用数据类型两种。包含字符串、数字、对象、数组、函数、布尔值......
  • 你说你精通Java并发,那给我讲讲J.U.C吧
    J.U.C即java.util.concurrent包,为我们提供了很多高性能的并发类,可以说是java并发的核心。Concurrent包下所有类底层都是依靠CAS操作来实现,而sun.misc.Unsafe为我们提供了......
  • Java笔记(二):String类
    String代表的是Java中的字符串,String类⽐较特殊,它整个类都是被final修饰的,也就是说,String不能被任何类继承,任何修改String字符串的⽅法都是创建了⼀个新的字......
  • Java笔记(一):基础
    1.JDK和JRE的区别JDK(JavaDevelopmentKit)开发工具基本类库javac编译javap反编译javadoc运行环境JRE(JavaRuntimeEnvironment)3.Lambda表达式使......
  • 带你深入Java Log框架,彻底搞懂Log4J、Log4J2、LogBack,SLF4J
    最近系统被扫出来还在使用老旧的log4j,需要升级到最新的log4j。但是在升级的发现,Java相关的日志处理库有log4j,log4j2,slf4j和logback,初一看确实有点头大,那么区别是啥呢?......
  • Java三大版本。JDK、JRE、JVM
    JavaSE:标准版(桌面程序,控制台开发...)JavaME:嵌入式开发(手机,小家电...)JavaEE:E企业级开发(Web端,服务器开发...)JDK:javadevelopmentkitJava开发者工具JRE:javaruntimeen......
  • Java面试系列:基础知识点
    一、List、Set、Collection的区别 二、ArrayList和LinkedList的区别 三、HashMap和HashTable的区别TRANSLATEwithxEnglishArabicHebrewPolish......
  • java的流程控制-break continue
    breakcontinuebreak:在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break也在switch语句中使用) continue:在......
  • 谈谈Java面向对象设计的六大原则
    单一职责原则——SRP开闭原则——OCP里式替换原则——LSP依赖倒置原则——DIP接口隔离原则——ISP迪米特原则——LOD单一职责原则单一职责原则的定义是就一个类......
  • 谈谈你对Java中常用的几种线程池的理解
    为什么使用线程池为每个请求创建一个新线程的开销很大容易引起资源不足,造成浪费使用线程池的风险死锁、资源不足和线程泄漏。死锁当一组进程或线程中的每一个都在......