有趣的《三门实验》,颠覆了我的认知

243 阅读3分钟

大家好,我是Tabber,今天给大家分享一个有趣的数学实验《三门实验》,

这个实验直接颠覆了我的直觉认知,What ? 不可能?肯定是你算错了?

下面让我们一起看下这个有趣的实验吧。


什么是三门问题?

这个游戏的玩法是:参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,而另外两扇门后面则各藏有一只山羊, 选中后面有车的那扇门就可以赢得该汽车。当参赛者选定了一扇门,但未去开启它的时候,节目主持人会开启剩下两扇门的其中一扇有山羊的门(主持人知道每个门后面是什么)。

这个时候,主持人会给参赛者两个选择:

  • 换另一扇仍然关上的门
  • 坚持选择当前已选的门

问题是:哪一种选择会否增加参赛者赢得汽车的概率?

请你思考 5秒钟 后做出自己的选择后,咱们继续开车...

思考5秒钟


揭晓答案

正确的选择:选择换门的胜率更大

  • 选择换门的胜率为66.6%
  • 选择不换的胜率为33.3%

知道答案哪一刻,我不知道你的表情是怎样的,但我的表情应该是这样的\

想必大家的思路都是这样的:

第一次选择,我的胜率为33.3% ,主持人打开一个为山羊的门后,只剩下一辆车和一只山羊,很明显剩余两扇门为车的概率都应为50% ,所以我选择不换的概率都应为50%

嗡,再想了想,好像没啥问题也,正确的选择怎么会是换的胜率更大呢?

验证过程

无法理解答案后,作为一名软件工程师,咱们最擅长的不就是写代码嘛,来搞一套,验证一下,肯定是出题人搞错了,我要用大量数据验证摆在你面前,看看谁错了?一脸傲娇!

/**
 * 验证 三门实验 示例
 * author:Java知己
 */
public class ThreeDoorExperiment {

    /**
     * 示例比较简单,直接一个main方法搞定
     * 也方便小伙伴们直接下载测试
     * @param args
     */
    public static void main(String[] args) {
        //成功次数
        int success = 0;

        //实验次数
        int count = 0;

        //三个门,0表示羊,1表示车
        int[] doors = {0, 0, 0};

        Random random = new Random();

        while (true){
            // 每次重置三个门为羊
            for(int i=0;i<doors.length;i++){
                doors[i] = 0;
            }

            // 将随机一个门置为车
            int right = random.nextInt(doors.length);
            doors[right] = 1;

            // 我随机选择一个门(第一次选择)
            int my_select_first = random.nextInt(doors.length);

            // 计算剩余两个门的和,判断是否有车
            int result = 0;

            // 剩余门的索引
            List<Integer> remain_doors_index_list = new ArrayList<>();
            for(int i=0;i<doors.length;i++){
                if(i == my_select_first){
                    continue;
                }
                remain_doors_index_list.add(i);
                result += doors[i];
            }

            //主持人打开门的第几个门
            int opened_rel = -1;
            // 主持人随机打开另外两个中的一个(必须是羊的一个门)
            if(result == 0){
                // 如果两个门都是羊,随机一个
                int remain_door_random = random.nextInt( remain_doors_index_list.size() );
                opened_rel = remain_doors_index_list.get(remain_door_random);
            }else{
                // 如果两个门只有一个是羊,只能打开这一个
                for(int index:remain_doors_index_list){
                    if(doors[index] == 0){
                        opened_rel = index;
                    }
                }
            }

            // 是否换另一个门
            boolean switch_door = true;
            //如果选择换,第二次的选择索引
            Integer my_select_two = null;
            if(switch_door){
                for(int i=0;i<doors.length;i++){
                    if(i != my_select_first && i != opened_rel){
                        my_select_two = i;
                        break;
                    }
                }
            }

            // 判断我的选择是否正确
            if(switch_door){
                if(my_select_two == right){
                    success ++;
                }
            }else{
                if(my_select_first == right){
                    success ++;
                }
            }

            count ++;
            // 当前成功概率
            System.out.println("当前门状态:" + Arrays.toString(doors));
            if(switch_door){
                System.out.println(String.format("我的选择:%d,打开门为:%d,更换的门为:%d,正确的门为:%d",my_select_first, opened_rel,my_select_two, right));
            }else{
                System.out.println(String.format("我的选择:%d,打开门为:%d,正确的门为:%d",my_select_first, opened_rel, right));
            }

            double successP = success * 100 / (double)count;
            System.out.println(String.format("当前我的成功概率为:%.2f%%,总实验次数为:%d",successP, count));
            System.out.println("-------------------------------------------------------------------");
        }

    }
}

实验结果

来咱们先跑一下

换门的胜率是多少?

当前门状态:[0, 1, 0]
我的选择:0,打开门为:2,更换的门为:1,正确的门为:1
当前我的成功概率为:100.00%,总实验次数为:1
-------------------------------------------------------------------
当前门状态:[0, 0, 1]
我的选择:1,打开门为:0,更换的门为:2,正确的门为:2
当前我的成功概率为:100.00%,总实验次数为:2
-------------------------------------------------------------------
当前门状态:[1, 0, 0]
我的选择:0,打开门为:2,更换的门为:1,正确的门为:0
当前我的成功概率为:66.67%,总实验次数为:3
-------------------------------------------------------------------
...
...省略中间N次过程
...
当前门状态:[0, 0, 1]
我的选择:1,打开门为:0,更换的门为:2,正确的门为:2
当前我的成功概率为:66.64%,总实验次数为:253603
-------------------------------------------------------------------
当前门状态:[0, 1, 0]
我的选择:2,打开门为:0,更换的门为:1,正确的门为:1
当前我的成功概率为:66.64%,总实验次数为:253604
-------------------------------------------------------------------
当前门状态:[0, 0, 1]
我的选择:0,打开门为:1,更换的门为:2,正确的门为:2
当前我的成功概率为:66.64%,总实验次数为:253605
-------------------------------------------------------------------

再来一次不换的胜率是多少?

//是否换另一个门
boolean switch_door = false;

修改switch_door 为 false,表示在第二次选择时,不更换门

修改switch_door 为 false,表示在第二次选择时,不更换门
当前门状态:[1, 0, 0]
我的选择:1,打开门为:2,正确的门为:0
当前我的成功概率为:0.00%,总实验次数为:1
-------------------------------------------------------------------
当前门状态:[0, 1, 0]
我的选择:1,打开门为:2,正确的门为:1
当前我的成功概率为:50.00%,总实验次数为:2
-------------------------------------------------------------------
当前门状态:[0, 1, 0]
我的选择:0,打开门为:2,正确的门为:1
当前我的成功概率为:33.33%,总实验次数为:3
-------------------------------------------------------------------
...
...省略中间N次过程
...
当前门状态:[0, 0, 1]
我的选择:0,打开门为:1,正确的门为:2
当前我的成功概率为:33.34%,总实验次数为:206159
-------------------------------------------------------------------
当前门状态:[0, 1, 0]
我的选择:0,打开门为:2,正确的门为:1
当前我的成功概率为:33.34%,总实验次数为:206160
-------------------------------------------------------------------
当前门状态:[1, 0, 0]
我的选择:1,打开门为:2,正确的门为:0
当前我的成功概率为:33.34%,总实验次数为:206161
-------------------------------------------------------------------

啊,打脸了,验证完的确是自己的直觉错了,但究竟是哪个环节出了问题呢?

认知分析

初始概率会随着后续事件不断调整

我们第一次选择后的概率为33.3%,这个是毫无疑问的,但后续事件(主持人开一扇为羊的门)后,原本门的概率都发生的改变。

站在全局的角度,你选择之后,主持人会开一个有山羊的门;你不换门,概率固定为1/3;你换门,相当于主持人给你排除了一个错误答案,所以概率变成了2/3。

如果是主持人已经开了门的时候,这个时候你再进行第一次选择,那么这个时候二选一,概率才为50%。

总结

这条问题亦被叫做蒙提霍尔悖论:虽然该问题的答案在逻辑上并不自相矛盾,但十分违反直觉。这问题曾引起一阵热烈的讨论。

我们看到,一个看似毫无意义的行为,竟然能为决策者提供如此多的信息。那么在更为复杂的博弈中,找到对手留下的蛛丝马迹便尤为重要。


有热门推荐

1. 再见了Xshell、iTerm2,这款开源的终端工具真香!

2. 95年女程序员内心的感受

3. Intellij IDEA 2022 正式发布,这些功能还真不错

4. 又一款接私活神器!SpringBoot+Vue通用后台管理系统

老规矩,文末上图 老规矩,文末上图