三门问题(Monty Hall problem),是一个源自博弈论的数学游戏问题,大致出自美国的电视游戏节目Let’s Make a Deal。问题的名字来自该节目的主持人蒙提·霍尔(Monty Hall)。
这个游戏的玩法是:参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,选中后面有车的那扇门就可以赢得该汽车,而另外两扇门后面则各藏有一只山羊。当参赛者选定了一扇门,但未去开启它的时候,节目主持人会开启剩下两扇门的其中一扇,露出其中一只山羊。主持人其后会问参赛者要不要换另一扇仍然关上的门。问题是:换另一扇门会否增加参赛者赢得汽车的机会率?如果严格按照上述的条件的话,答案是会—换门的话,赢得汽车的机会率是 2/3。
首先,我们怎么用概率的知识来思考这个问题。
我们一般接触到的实际问题都是先验概率,很多事情都是相对独立事件,即一件事的发生不会影响另一件事的概率;但是这个三门问题,却是一道条件概率问题。即后发生的事件会对之前的事件产生影响,从而影响之前事件概率。
条件概率: 事件A在另外一个事件B已经发生条件下的发生概率。条件概率表示为P(A|B),读作“在B条件下A的概率”。若只有两个事件A,B,那么,
利用编程的逻辑思维,实现三门问题,代码如下
function main(changeFlag) {
// changeFlag 表示是否换门
var doors, // 表示门的数组
trueNum, // 表示真门的位置
choseDoor, // 表示玩家选择的门
exculdeNum // 表示主持人排除的假门
// 两扇假门
doors = ['false', 'false']
// 随机函数
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
// 随机真门位置
trueNum = getRandom(0, 2);
// var getRandom = Math.floor(Math.random() * 3);
// trueNum = Math.floor(Math.random() * 3);
// 插入真门
doors.splice(trueNum, 0, 'true')
// 选择的门
choseDoor = doors.splice(getRandom(0, 2), 1)
// 剩下两扇门中排除一扇假门
if (doors[0] === doors[1]) {
exculdeNum = getRandom(0, 1)
} else {
exculdeNum = doors.findIndex(function(item) {
return item === 'false'
})
}
doors.splice(exculdeNum, 1)
// 是否换门
if (changeFlag) {
return doors[0]
} else {
return choseDoor[0]
}
}
// 测试函数
function test() {
var total = 100000, // 测试次数
count = 0, // 计数器 第几次测试
changeTotal = 0, // 换门中奖的次数
notChangeTotal = 0; // 不换门中奖的次数
while (count < total) {
// 换门后中奖的次数
if (main(true) === 'true') {
changeTotal++
}
// 不换门后中奖的次数
if (main(false) === 'true') {
notChangeTotal++
}
count++
}
console.log('换门:' + changeTotal);
console.log("不换门:" + notChangeTotal)
}
test()
可以看出换门后获奖的概率为2/3。