Monty Hall Problem

蒙提霍尔三门问题,看到这个问题的描述和答案后。有点不理解,后来看了点其他文章,然后也写了代码验证,弄明白这个问题了。

百度百科上面关于这个问题的描述也是正确的。百度百科对三门问题的解释

Monty Hall Problem:

Monty Hall Problem_第1张图片

这个问题是说,如上图,游戏中有3个一样的门,门后面有奖励,一条门后面是汽车,另外2条门后面是羊。一开始让你选择一条门,比如你像图中一样选了门1。然后主持人/游戏 会在另外的2条门之中打开一扇门,比如打开了门3,然后如果你看到的是羊的话,问你要不要更改选择。如下图所示。问这时继续选门1和换选门2,赢的概率分别是多少。

Monty Hall Problem_第2张图片


针对这个问题的验证代码:

# -*- coding: utf-8 -*-
"""
Created on Mon Jun 11 20:16:48 2018

@author: Administrator
"""

import random

N = 80001

def setAprize():
    x = random.randint(1,3)
    return x

def put1stChoise():
    x = random.randint(1,3)
    return x

# 主持人在未选中的2条门中随机打开一个
def openAdoorFrom2(selectedDoor):
    y = random.randint(0,1)
    doorlist = [1,2,3]
    doorlist.remove(selectedDoor)
    return doorlist[y]

# 主持人在未选中的2条门中特意打开山羊的那个
def openSheepdoorFrom2(selectedDoor, prizeDoor):
    doorlist = [1,2,3]
    doorlist.remove(selectedDoor)

    if doorlist.count(prizeDoor) == 0:
        x = random.randint(0,1)
        return doorlist[x]

    doorlist.remove(prizeDoor)
    return doorlist[0]

def runMontyHallGame():
    print('----------每次测试的样本总量是:', N)
    resultlist = []
    for i in range(N):
        prizeDoor = setAprize()
        firstChoice = put1stChoise()
        theOpenedDoor = openAdoorFrom2(firstChoice)
        # 打开的门是奖赏,不是山羊,不采样。
        if theOpenedDoor == prizeDoor:
            continue

        win = 0
        if firstChoice == prizeDoor:
            win = 1
        resultlist.append(win)
    print('----------主持人每次从未选择的2条门中随机打开一个,坚持选原来门,赢的概率:')
    print('len of resultlist is: ', len(resultlist), ', win probability is: ', \
          1.0*sum(resultlist)/(len(resultlist)))
    
    print('----------主持人每次从未选择的2条门中打开山羊的那个,坚持选原来门,赢的概率:')
    resultlist = []
    for i in range(N):
        prizeDoor = setAprize()
        firstChoice = put1stChoise()
        theOpenedDoor = openSheepdoorFrom2(firstChoice, prizeDoor)
        # 打开的门总是山羊,因为主持人选择的规则。
        if theOpenedDoor == prizeDoor:
            continue

        win = 0
        if firstChoice == prizeDoor:
            win = 1
        resultlist.append(win)
    
    print('len of resultlist is: ', len(resultlist), ', win probability is: ', \
          1.0*sum(resultlist)/(len(resultlist)))

runMontyHallGame()

代码里面,针对主持人的2种选择策略,分别写了代码验证,打印的结果是:

----------每次测试的样本总量是: 80001
----------主持人每次从未选择的2条门中随机打开一个,坚持选原来门,赢的概率:
len of resultlist is:  53467 , win probability is:  0.5004208203190753
----------主持人每次从未选择的2条门中打开山羊的那个,坚持选原来门,赢的概率:

len of resultlist is:  80001 , win probability is:  0.33073336583292706


所以这里的概率认知分歧在于主持人从另外2条门里面的选择开的门是随机的还是有意的选择山羊的门。

如果随机的选择,那问题就是一个不放回抽样问题了。剩下门的选择概率就是0.5,0.5。

每次有意选择是山羊的门,导致剩下门赢的概率变为:原选择门1/3,另外一条门2/3

你可能感兴趣的:(小程序)