为什么我的Monty Hall解决方案不起作用?

时间:2013-12-29 19:01:39

标签: python algorithm logic probability

以下代码是我的实现(Python 3.3.1),看看我是否可以证明切换在Monty Hall问题中是有效的。当我让玩家保持他们的第一选择时,我会得到大约0.33的正确猜测结果,这是预期的。当我有玩家切换时出现问题 - 而不是达到预期的~0.66,我一直得到~0.55。

任何人都可以看到错误吗? (另外,作为旁注,我可以对代码做出任何改进)

def runInstance(switch): #run a single Monty Hall Problem instance
    choicesList = [False,False,False]
    intTruth = randint(0,2)
    choicesList[intTruth] = True #list has been set up with 2 False, 1 True
    intChoice = randint(0,2)
    for index in range(0,len(choicesList)): #Loop finds entry index which is not chosen and is False to "present" to player
        if( (intChoice != index) and (choicesList[index] == False) ):
            alternate = index
    if(switch):
        for index in range(0,len(choicesList)): #Loop finds entry index which hasn't been chosen, and isn't the "Opened Door", then switches to it
            if( (index != intChoice) and (index != alternate) ):
                intChoice = index
    return choicesList[intChoice]

def runBatch(inputSize, switch): #Run batch of instances for stats
    successCount = 0.0
    for index in range(0,int(inputSize)):
        if(runInstance(switch)):
            successCount += 1.0
    print(str(successCount/inputSize))

runBatch(100000.0, True) #Number of instances to run, and boolean indicating whether to switch

3 个答案:

答案 0 :(得分:4)

将代码更改为:

origChoice = intChoice
if(switch):
    for index in range(0,len(choicesList)): #Loop finds entry index which hasn't been chosen, and isn't the "Opened Door", then switches to it
        if( (index != origChoice) and (index != alternate) ):
            intChoice = index

问题在于,有时您会切换然后切换回原来的选择。

换句话说,如果intChoice = 2,则= = 1然后:

  1. 在第一次交互时,intChoice将更改为0
  2. 在第二次迭代中,不会发生任何事情(因为索引==替代)
  3. 在第三次迭代中,intChoice将变回2

答案 1 :(得分:1)

如你所见,你需要休息一下:

    if(switch):
        for index in range(0,len(choicesList)): #Loop finds entry index which hasn't been chosen, and isn't the "Opened Door", then switches to it
            if( (index != intChoice) and (index != alternate) ):
                intChoice = index
                break

为了回答你问题的第二部分,这是我的实现:

import random

def monty_hall(switch):
    correct = random.randint(0, 2)
    choice = random.randint(0, 2)
    known_false = ({0, 1, 2} - {choice, correct}).pop()

    if switch:
        choice = ({0, 1, 2} - {choice, known_false}).pop()

    return choice == correct

def simulate_many(number, switch):
    number_correct = sum(monty_hall(switch) for _ in range(number))

    print(number_correct / number)

simulate_many(10000, True)

(对于Python 3; Python 2可能需要进行一些更改。)

  • 使用set操作代替循环来查找不需要的索引。然后结果是pop ed。

  • 尽量不要假装语言被输入,或者它是Java:它不是。

  • int(inputSize)有什么用?你想允许str被传入吗?还是非整体浮子?让来电者处理。

  • 也没有必要保留一份清单。

答案 2 :(得分:1)

这是一个简短易读的版本:

def mh(trials=1000):
    kept, switched = 0, 0
    for trial in range(trials):
        behind_curtains = ['goat', 'goat', 'boat']
        shuffle(behind_curtains)
        kept += behind_curtains.pop() is 'boat'
        behind_curtains.remove('goat')
        switched += behind_curtains[0] is 'boat'
    print ('Keeping 1st choice won {} times. \n'
           'Switching choice won {} times').format(kept, switched)