问题起源
三门问题(Monty Hall problem)亦称为蒙提霍尔问题、蒙特霍问题或蒙提霍尔悖论,大致出自美国的电视游戏节目Let’s Make a Deal。问题名字来自该节目的主持人蒙提·霍尔(Monty Hall)。参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,选中后面有车的那扇门可赢得该汽车,另外两扇门后面则各藏有一只山羊。当参赛者选定了一扇门,但未去开启它的时候,节目主持人开启剩下两扇门的其中一扇,露出其中一只山羊。主持人其后会问参赛者要不要换另一扇仍然关上的门。问题是:换另一扇门会否增加参赛者赢得汽车的机率?如果严格按照上述的条件,即主持人清楚地知道,自己打开的那扇门后是羊,那么答案是会。不换门的话,赢得汽车的几率是 1 3 \frac{1}{3} 31。换门的话,赢得汽车的几率是 2 3 \frac{2}{3} 32。
源码实现
源码
package com.lyc;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.junit.Before;
import org.junit.Test;
import java.util.*;
/**
* @author: zhangzhenyi
* @date: 2019/8/11 23:38
* @description:
**/
@Slf4j
public class MontyHallTest {
// 汽车、山羊集合
List<String> targetList = Lists.newArrayList();
// 容器集合
List<Container> containerList = Lists.newArrayList();
/**
* 被选择对象
*/
@Getter
@AllArgsConstructor
public enum Names {
CAR("汽车"),
GOAT("山羊");
private String name;
}
/**
* 容器枚举对象
*/
public enum ContainerEnum{
A,
B,
C;
}
/**
* 构造容器
*/
@Data
@AllArgsConstructor
public class Container{
// 容器名称
private String index;
// 容器中的物品
private String name;
}
/**
* 数据初始化
*/
@Before
public void init(){
// 准备汽车与山羊
targetList.add(Names.CAR.getName());
targetList.add(Names.GOAT.getName());
targetList.add(Names.GOAT.getName());
// 准备容器
containerList.add(new Container(ContainerEnum.A.name(),""));
containerList.add(new Container(ContainerEnum.B.name(),""));
containerList.add(new Container(ContainerEnum.C.name(),""));
}
/**
* 蒙提霍尔问题
*/
@Test
public void testMontyHall(){
// 循环次数
int cycleTime = 90000;
// 选对次数
double correct = 0;
// 选错次数
double error = 0;
// 选对与选错之比
double result = 0;
// 循环遍历多次执行
for(int i = 0; i < cycleTime; i ++){
// 如果选对,则对的+1,否则错的+1
if(choiceEle()){
correct ++;
} else {
error ++;
}
}
// 计算选择结果
result = correct / error;
// 在控制台中打印最终的结果
log.info("选对的次数为:{},选错的次数为:{},选对与选错之比:{}",correct,error,result);
}
/**
* 每次选择
* @return boolean
*/
private boolean choiceEle() {
// 随机产生山羊与汽车,并将其放入到容器中
List<