三门问题讨论
- 三门问题
- 第一种
- 第二种
三门问题
三门问题(Monty Hall problem)亦称为蒙提霍尔问题、蒙特霍问题或蒙提霍尔悖论,大致出自美国的电视游戏节目Let’s Make a Deal。问题名字来自该节目的主持人蒙提·霍尔(Monty Hall)。参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,选中后面有车的那扇门可赢得该汽车,另外两扇门后面则各藏有一只山羊。当参赛者选定了一扇门,但未去开启它的时候,节目主持人开启剩下两扇门的其中一扇,露出其中一只山羊。主持人其后会问参赛者要不要换另一扇仍然关上的门。问题是:换另一扇门是否会增加参赛者赢得汽车的机率。如果严格按照上述的条件,那么答案是会。不换门的话,赢得汽车的几率是1/3。换门的话,赢得汽车的几率是2/3。
这里有两种Java模拟程序,
第一个结论是不换门的话,赢得汽车的几率是1/3。换门的话,赢得汽车的几率是2/3。
第二个结论是换不换门结果都一样。
你支持哪一种写法呢?
第一种
public class ThreeDoorSolution {
public static void main(String[] args) {
// 模拟执行1万次,打印获胜的概率
threeDoor(10000);
}
/**
* 三门问题逻辑拆解
*
* @param numSimulations 总共执行多少轮游戏
*/
private static void threeDoor(int numSimulations) {
int switchWins = 0;
int stayWins = 0;
Random random = new Random();
for (int i = 0; i < numSimulations; i++) {
// 随机确定车所在的门
int carDoor = random.nextInt(3);
// 玩家随机选择一扇门
int playerChoice = random.nextInt(3);
// 主持人随机打开一扇门:要求该门不是玩家选择的,且必须是羊
int openedDoor;
do {
openedDoor = random.nextInt(3);
} while (openedDoor == carDoor || openedDoor == playerChoice);
// 换门后的选择:不能是打开的门,不能是玩家选择的门,则是交换之后的门
int finalChoice;
do {
finalChoice = random.nextInt(3);
} while (finalChoice == playerChoice || finalChoice == openedDoor);
// 计算是否换门获胜
if (finalChoice == carDoor) {
switchWins++;
}
// 计算不换门获胜
if (playerChoice == carDoor) {
stayWins++;
}
}
// 输出结果
System.out.println("在 " + numSimulations + " 次模拟中:");
System.out.println("换门获胜的概率:" + (double) switchWins / numSimulations);
System.out.println("不换门获胜的概率:" + (double) stayWins / numSimulations);
}
}
在 10000 次模拟中:
换门获胜的概率:0.674
不换门获胜的概率:0.326
第二种
package com.jd.edi.robam;
import java.util.Random;
public class ThreeDoorSolution {
public static void main(String[] args) {
// 模拟执行1万次,打印获胜的概率
threeDoor(1000000);
}
/**
* 三门问题逻辑拆解
*
* @param numSimulations 总共执行多少轮游戏
*/
private static void threeDoor(int numSimulations) {
int switchWins = 0;
int stayWins = 0;
Random random = new Random();
int total = 0;
for (int i = 0; i < numSimulations; i++) {
// 随机确定车所在的门
int carDoor = random.nextInt(3);
// 玩家随机选择一扇门
int playerChoice = random.nextInt(3);
// 主持人随机打开一扇门:要求该门不是玩家选择的,且必须是羊
int openedDoor = random.nextInt(3);
if (openedDoor == carDoor || openedDoor == playerChoice) {
continue;
}
// 换门后的选择:不能是打开的门,不能是玩家选择的门,则是交换之后的门
int finalChoice = random.nextInt(3);
if (finalChoice == playerChoice || finalChoice == openedDoor) {
continue;
}
// 计算是否换门获胜
if (finalChoice == carDoor) {
switchWins++;
}
// 计算不换门获胜
if (playerChoice == carDoor) {
stayWins++;
}
total++;
}
// 输出结果
System.out.println("在 " + numSimulations + " 次模拟中,有效模拟" + total + "次,其中:");
System.out.println("换门获胜的概率:" + (double) switchWins / total);
System.out.println("不换门获胜的概率:" + (double) stayWins / total);
}
}
在 1000000 次模拟中,有效模拟148182次,其中:
换门获胜的概率:0.5003104290669582
不换门获胜的概率:0.4996895709330418