关于阵列的Monty Hall模拟问题

时间:2014-06-27 20:16:57

标签: arrays logic simulation

我遇到了一个模拟问题,我做的是" Montey Hall"统计谜语。我的答案应该得到一致的结果(33%/ 66%),但每次运行模拟时,结果最终为0/100,然后翻到66%/ 33%。我相信问题可能在于我如何创建我的阵列(即一个模拟的结果正在流入下一个模拟),但我无法确定问题。另外,如果您有关于更好地编写模拟的方法的任何提示,我也会很感激。

以下是我的代码

#simulates guessing a door
def sim_guess(nsim):
    answer = []
    guess = [0,1,2]
    stratagy = [0.2,0.6,0.2]
    for element in range(nsim):
        answer.append(np.random.choice(guess, p=stratagy))
    return answer

#simulates placing the prize
def simulate_prizedoor(nsim):
    doors = [0,1,2]
    answer = []
    for element in range(nsim):
        answer.append(np.random.choice(doors))
    return answer

#simulates opening a door to reveal a goat
def goat_door(prize, guess):
    answer = []
    for i in range(len(prize)):
        door = [0,1,2]
        if prize[i] == guess[i]:
            door.remove(prize[i])
            answer.append(np.random.choice(door))
        else:
            door.remove(prize[i])
            door.remove(guess[i])
            answer.append(door[0])
    return answer

#simulates changing guess after goat has been revealed
def switch_guess(goat, guess):
    answer = []
    for i in range(len(goat)):
        door = [0,1,2]
        door.remove(goat[i])
        door.remove(guess[i])
        answer.append(door[0])
    return answer
#shows percentages after 10,000 trials
def win_percentage(prize, guess):
    wins = []
    for element in prize:
        wins.append(prize[element] == guess[element])

    answer = (float(np.sum(wins))/len(guess))*100
    return answer

prize = simulate_prizedoor(10000)
guess = sim_guess(10000)

#wins without changing guess
print win_percentage(prize, guess)

#wins with changing guess
goat = goat_door(prize, guess)
switch = switch_guess(goat, guess)
print win_percentage(prize, switch)

1 个答案:

答案 0 :(得分:0)

我觉得使用对象会更容易,因为每个游戏都与其他游戏分开。我可能会这样做

import random

class Game:
        winningDoor = 0
        chosenDoor = 0
        goat = 0
        def __init__(self):
                self.winningDoor = random.randint(1,3)
        def play(self, move, willSwap):
                self.chosenDoor = move
                self.goat = 0
                i=1
                while(self.goat <= 0):
                        if(i != self.winningDoor and i != self.chosenDoor):
                                self.goat = i
                        i += 1
                if(willSwap):
                        self.chosenDoor = 6-(self.chosenDoor + self.goat)
                return (self.winningDoor == self.chosenDoor)


def main():
        swapwins = 0
        staywins = 0
        for i in range(0,10000):
                testswap = Game()
                if(testswap.play(random.randint(1,3), 1)):
                        swapwins += 1
                teststay = Game()
                if(teststay.play(random.randint(1,3), 0)):
                        staywins += 1
        print swapwins, staywins

main()

这里,每个游戏都是单独制作的,每个游戏都要玩一次。它不是对象的最有效使用,并且可能只是一个子程序,但如果你想要更多的统计数据,这将最终变得更好。这里唯一可能令人困惑的事情是

self.chosenDoor = 6-(self.chosenDoor + self.goat)

这是一个简化的声明,如果选择山羊是1和2,将其改为3;如果选择山羊2和3,则将其改为1;如果山羊为3并且选择为1,则将其更改为2;等等... 至于为什么你的原始代码不起作用,以10000为一组返回所有东西看起来很奇怪而且很难调试。您的随机数也可以使用randint完成,这也会使您的代码更具人性化。