三门问题来源于一个娱乐节目。节目中有一位参与者和一位主持人,在参与者的面前有三扇关闭的门,其中两扇门的后面是空的,剩下一扇门后是一辆法拉利跑车。当参赛者选定了一扇门,但未去开启它的时候,节目主持人开启剩下两扇门的其中一扇,是空门。主持人其后会问参赛者要不要换另一扇仍然关上的门。
本质问题是换另一扇门会否增加参赛者赢得汽车的机会率?网上统一的答案是“会”,但是我发现有一个很重要的一点都被网上的文章忽略了,主持人他知道中奖的门吗?
一、代码验证
此处列举一个网上的 Java 代码验证问题的实例:
import java.util.Random;
public class Test {
public static void main(String[] args) {
// 测试次数
int n = 10000;
//换门的获奖总次数
int changeWinCount = 0;
//不换门的获奖总次数
int unChangeWinCount = 0;
Random random = new Random();
for (int i = 0; i < n; i++) {
// 获奖的门
int bonusDoor = random.nextInt(3);
// 选中的门
int selectedDoor = random.nextInt(3);
// 如果选中的门就是获奖的门,那么不换门得奖,反之换门可以得奖
if (selectedDoor == bonusDoor) {
unChangeWinCount++;
} else {
changeWinCount++;
}
}
System.out.println("不换门获奖总次数:" + unChangeWinCount + ",比例:" + (float) unChangeWinCount / (changeWinCount + unChangeWinCount));
System.out.println("换门获奖总次数:" + changeWinCount + ",比例:" + (float) changeWinCount / (changeWinCount + unChangeWinCount));
}
}
这个程序的运行输出大致为:
不换门获奖总次数:3336,比例:0.3336
换门获奖总次数:6664,比例:0.6664
根据这个结果,我们很容易就可以得出结论,不换门的获奖概率为 1/3
,换门的获奖概率为 2/3
。
但是事实是这样嘛,在上面的案例中并没有详细的考虑到主持人开门的细节。
二、主持人是如何开门的?
在上面的案例代码中仅判断了选中的门是否是中奖的门,稍微有些统计常识的同学都可以立即的出中奖概率为 1/3
的结论。但是这个三门问题应该还应该更加细化的考虑一点,主持人知道中奖的门是哪个吗?
- 主持人知道: 主持人知道中奖的门,可以准确的打开未中奖的门,可以无须考虑主持人是否开门。
- 主持人不知道: 主持人不知道中奖的门是哪个,有一定的几率打开的是中奖的门,那么这局游戏应该重开。而主持人打开中奖的门的概率是
2/3 * 1/2 = 1/3
。
当主持人不知道中奖门时的验证代码:
import java.util.*;
public class Test {
public static void main(String[] args) {
// 测试次数
int n = 10000;
//换门的获奖总次数
int changeWinCount = 0;
//不换门的获奖总次数
int unChangeWinCount = 0;
Random random = new Random();
for (int i = 0; i < n; i++) {
|+ // 主持人可打开的门
|+ List<Integer> doors = new ArrayList<>(Arrays.asList(0, 1, 2));
// 获奖的门
int bonusDoor = random.nextInt(3);
// 选中的门
int selectedDoor = random.nextInt(3);
|+ // 选中的门不可打开
|+ doors.remove(selectedDoor);
|+ // 剩余的两个门中主持人选中一个打开
|+ int compereSelectedDoor = doors.get(random.nextInt(2));
|+ // 如果主持人选中中奖的门则作废
|+ if (compereSelectedDoor == bonusDoor) {
|+ continue;
|+ }
// 如果参与者选中的门就是获奖的门,那么不换门得奖,反之换门可以得奖
if (selectedDoor == bonusDoor) {
unChangeWinCount++;
} else {
changeWinCount++;
}
}
System.out.println("不换门获奖总次数:" + unChangeWinCount + ",比例:" + (float) unChangeWinCount / (changeWinCount + unChangeWinCount));
System.out.println("换门获奖总次数:" + changeWinCount + ",比例:" + (float) changeWinCount / (changeWinCount + unChangeWinCount));
}
}
这个程序的运行输出大致为:
不换门获奖总次数:3380,比例:0.5047036
换门获奖总次数:3317,比例:0.4952964
通过以上结果可以看到,有 1/3
的局数被作废了,换门和不换门的获奖概率一致,都为 1/3
。
三、总结
这道题的重点就在于主持人选中中间门时的处理上,网上的代码示例都未考虑到主持人有概率选到中奖门这个情况。或者说都默认主持人知道中奖门,不会选错。于是未将主持人选中中间门的概率排除掉,并将这个概率合并到了换门获奖的概率中。所以有了 1/3
和 2/3
的这个中奖率的差别。
PS:这个三门问题是在主持人知道中间门的前提下进行的。本身这是一个很简单的概率问题,只是一些文章作者没有注意到这一点,并没有说明主持人知道中奖门的前提,直接就说不换门和换门的中奖概率是
1/3
和2/3
,这才导致了争议。