本文编写于 585 天前,最后修改于 585 天前,其中某些信息可能已经过时。

蒙提霍尔三门问题

三门问题——亦称为蒙提霍尔问题,出自美国的电视游戏节目Let's Make a Deal。问题的名字来自该节目的主持人蒙提·霍尔(Monty Hall)。问题是这样的:

(15分)你的面前有一模-样的三扇门,你选定其中一扇门后就可以得到该门背后的东西。只有一- 扇门的背后有你梦寐以求的高级跑车,剩下两扇门的背后只有羊。有位主持人知道每扇门背后的详细情况。主持人先让你选择-一个门, 你选择后告诉了他,他再把另一个不是你选的门打开,告诉你里面是羊。现在只剩两扇门了,一扇是你刚开始选的,另一扇是主持人没有打开的。现在主持人问你:你是坚持你--开始的选择呢,还是换到另--扇剩下的门?请你通过编写随机模拟代码来确认你的结论。 (你可以使用任何语言的代码,或仅采用伪代码描述)

普通算法

思路一:逆向思考:

   如果主持人问你换不换的时候,你坚决不换,你参加了1000次,主持人问了你1000次,你都说我不换。那好,主持人给你的提示对你没有影响,也就是说,主持人开剩下的两道门之一,对你没有任何影响。什么意思呢?就是你做的事情就是三选一,那你1000次参加,大概你能中奖333次。不换的结果就是中奖概率是三分之一。

  所以你换的话,就是2/3的概率中奖。这是从反面来推测的。

思路二,直接法,等价推转换。我觉得这种理解最好。。

  还是假设你参加了1000次这样的活动吧,我们把问题这样转换以下会变得非常有意思。你选了三张门中的一个,现在主持人问你:给你一次机会,你可以放弃你手里的一张门,而选我这边的两扇门(两扇门都归你,后面有可能有一车一羊,或两只羊),不过你得把你这两扇门后的一只羊给我,你换不换?

  换,当然换,每次可以选两张门,这样概率是多大,当然是2/3了。

如何用计算机语言解决数学问题

大概懂了,那就是用高频尝试求概率

javascript解法

我感觉写了很长时间,事实证明如果我考试考到这题基本上就没办法了。。。当然还可以继续优化

//三门问题
function hostOpen(select,array){
    //给出主持人打开的门的序号
    var n = 0  //n是主持人打开的那扇门的序号
    if(array[select]){
        //如果选的就是跑车序号
        while(n == select){
            n = randomNum(0,2)
        }
    }else{
        //如果选的不是跑车序号
        while(n==select||array[n]==true){
            n = randomNum(0,2)
        }
    }
    return n
}

function changeOpen(host,select){
    //给出更换后的我选择的门的序号
    return 3-host-select
}

function isWin(select,array){
    //是否胜利
    if(array[select]){
        return true
    }else{
        return false
    }
}

function randomNum(minNum,maxNum){ 
    //生成a和b之间的随机整数
    switch(arguments.length){ 
        case 1: 
            return parseInt(Math.random()*minNum+1,10); 
        break; 
        case 2: 
            return parseInt(Math.random()*(maxNum-minNum+1)+minNum,10); 
        break; 
            default: 
                return 0; 
            break; 
    } 
} 

function main(){
    var count = 1000
    var changeWin = 0
    var directWin = 0

    var select = 0 
    var host = 0
    var change = 0

    for (var i = 0;i<count;i++){
        var list = [false,false,false]
        car = randomNum(0,2)
        list[car]=true

        select = randomNum(0,2)
        host = hostOpen(select,list)
        change = changeOpen(host,select)

        // console.log("我选的是第"+(select+1)+"扇门")
        // console.log("主持人打开了第"+(host+1)+"扇门")
        // console.log("如果我不更换,那么我"+isWin(select,list))
        // console.log("如果我更换,我会更换打开第"+(change+1)+"扇门,同时我"+isWin(change,list))
        // console.log(list)
        if(isWin(select,list)){
            directWin ++
        }else{
            changeWin ++
        }
    }
    console.log("一共尝试"+count+"次,不改变赢"+directWin+"次,胜率"+(directWin/10000)+" 改变赢"+changeWin+"次,胜率"+(changeWin/10000))
}

main()

python解法

这个用了python的random库,似乎简单不少,43行

from random import choice

def stay():
    doors = ['car','goat','goat']       #设置三扇门,其中两扇门后面是山羊,一扇门后是汽车
    choose = choice(doors)              #随机选择一扇门
    if choose == 'car':                 #不换门则直接判断
        return 'win'
    else:
        return 'lose'

def switch():
    doors = ['car', 'goat', 'goat']
    choose = choice(doors)
    doors.remove(choose)               #选择的门放一边
    doors.remove('goat')               #剩下的门,去掉一只山羊
    if doors == ['car']:               #换门
        return 'win'
    else:
        return 'lose'

if __name__ == '__main__':
    total = 100000
    count_switch = 0
    win_switch = 0
    count_stay = 0
    win_stay = 0
    for i in range(total):
        choose = choice([1,2])          #随机选择换门还是不换门
        if choose == 1:
            count_switch += 1
            if switch() == 'win':
                win_switch += 1
        else:
            count_stay += 1
            if stay() == 'win':
                win_stay += 1

    print('换门次数:',count_switch)
    print('换门后得到汽车:',win_switch,'%.2f%%'%(100*win_switch/count_switch))
    print('不换门:',count_stay)
    print('不换门后得到汽车:',win_stay,'%.2f%%'%(100*win_stay/count_stay)) 
————————————————
版权声明:本文为CSDN博主「土豆洋芋山药蛋」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33414271/article/details/79321065

还有更短的

from random import*
x=randint(5000,10000)       #随机设定一个试验次数
first_choice=0
change_choice=0
for i in range(1,x+1):
    n=randint(1,3)           #随机生成一个数代表藏有汽车的数
    m=randint(1,3)           #随机生成一个数代表参赛者的选择
    if m==n:                 #参赛者没有改变选择
            first_choice+=1
    else:                    #参赛者改变了选择
            change_choice+=1
print("不更改选择,猜中汽车的几率为:{:.4f},更改选择,猜中汽车的几率为:{:4f}".format(first_choice/x,change_choice/x))