美文网首页
【随笔】关于玛丽莲问题的一些思考(附c++代码证明)

【随笔】关于玛丽莲问题的一些思考(附c++代码证明)

作者: Sheep98 | 来源:发表于2018-08-19 13:59 被阅读0次

    玛丽莲问题是一个十分有趣的概率问题,首先,它是违反人的第一直觉的。为什么会违反直觉?我们直接来看题目吧。

    玛丽莲问题:

    你参加一个电视节目,有3个门,其中2个门后是山羊,一个门后是汽车。节目过程是你先挑选一个门,然后主持人会从剩下的两个门中推开一扇藏有山羊的门,然后问你,如果为了赢得汽车,这个时候你是否改变原来的选择。

    这个问题也有另一个版本:

    有A,B,C三个盒子,已知其中一个装有礼物,另两个是空的,由你随便挑选其中一个而不打开。然后有个知道礼物放在哪个盒子中的人,把另两个盒子中没有礼物的那个打开,现在给你一个换选盒子的机会,即选择另一个剩下的。那么为了使您得到礼物的机会大一些,你选择换还是不换,为什么?

    思考

    为了方便说明,我选择了第二个对于我来说更方便解释的问题进行说明。首先为了选择,我们需要思考换还是不换的概率是多少。第一次看到这个问题,我直觉上来说是觉得都是二分之一的概率,应该没有差别。但是看到正确答案是选择换的话获奖概率为2/3,不换为1/3以后,我觉得很神奇,同时也产生了想用代码验证的想法。

    代码构思

    构造模型

    首先构造三个盒子的类,我选择用一个长度为三的bool数组模拟三个盒子,利用随机数选择让其中一个为true,其它两个为false

    class threeBox {
    public:
        bool box[3] = {false,false,false};            //先初始三个false
        threeBox() { box[rand() % 3] = true;}     //随机选择一个box为true
    };
    

    好了,构造好了三个box模型,接下来模拟一下第一次选择,利用一个int,保存我们在0-2里面随机的一个数,当作是我们第一次选中的,也就是box的数组下标。完成这些只需要在threeBox类上加上一点点:

    class threeBox {
    public:
        bool box[3] = {false,false,false};            //先初始三个false
        int firstSelect;                              //第一次选择
        /*随机一个box为true,然后随机选择一个box当作我们的第一次选择*/
        threeBox() { box[rand() % 3] = true; firstSelect = rand() % 3;  }    
    };
    

    到这里其实模型已经构建好了,接下来就是主持人进行选择。为了方便最后的结果显示够直白,我们选择用一个bool函数,返回主持人打开一个空盒子以后剩下的盒子里是有奖还是无奖的(其实机智的朋友这时可能已经反应过来这里才是关键的所在),构造的函数如下:

    bool threeBox::change() {
        int a[2];            //用来保存剩下的两个盒子的情况
        int cnt = 0;       //下标
        for (int i = 0; i < 3;i++) {
            if (i == firstSelect)continue;  //如果i等于第一次选择的,则跳过
            else a[cnt++] = box[i];          //保存未选择的盒子的状态
        }
    /*如果两个盒子都为空,则主持人开盒子以后另一个也为空
     *则假如我们选择交换,结果是空盒子,所以返回false
     */
        if (a[0] == false && a[1] == false) {
            return false;
        }
    /*如果其中一个盒子有奖,则拆另一个盒子
     *则我们交换的话就获奖了,返回true
     */
        else {
            return true;
        }
    }
    

    测试

    测试代码十分简单,直接上代码吧:

    int main() {
        int cnt = 0;      //保存获奖的次数
        for (int i = 0; i < 100000; i++) {
            threeBox b;
            if (b.change() == 1) {
                cnt++;
            }
            else continue;
        }
        cout << "the probability: " << cnt/1000 << "%" << endl;
        system("pause");
        return 0;
    }
    

    结果

    测试结果

    结果显示结果为66%,其实也就是三分之二。这道题目的正确答案应该是:

    • 选择换获奖概率:2/3
    • 不换的获奖概率:1/3

    我们的测试结果是符合正确答案的。

    思考

    其实在写交换函数的时候,写到判断的时候就已经知道答案了,因为此时的问题就是剩下的盒子里有无有奖的盒子,有奖的话我们选择换就必中,无奖的话我们选择换就不中。而剩下的两个里面有奖的概率是多少呢?不就是三分之二嘛!所以此时问题就迎刃而解了。我觉得这个问题乍看很摸不着头脑,自己模拟一遍思路就相当开阔了。

    最后附上全部代码:

    #include<iostream>
    #include<random>
    using namespace std;
    
    class threeBox {
    public:
        bool box[3] = {false,false,false};
        int firstSelect;
        threeBox() { box[rand() % 3] = true; firstSelect = rand() % 3;  }
        bool change();
    };
    
    bool threeBox::change() {
        int a[2];
        int cnt = 0;
        for (int i = 0; i < 3;i++) {
            if (i == firstSelect)continue;
            else a[cnt++] = box[i];
        }
        if (a[0] == false && a[1] == false) {
            return false;
        }
        else {
            return true;
        }
    
    }
    
    int main() {
        int cnt = 0;
        for (int i = 0; i < 100000; i++) {
            threeBox b;
            if (b.change() == 1) {
                cnt++;
            }
            else continue;
        }
        cout << "the probability: " << cnt/1000 << "%" << endl;
    
        system("pause");
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:【随笔】关于玛丽莲问题的一些思考(附c++代码证明)

          本文链接:https://www.haomeiwen.com/subject/onpqiftx.html