【问题标题】:Monty Hall simulation issue regarding arrays关于阵列的 Monty Hall 模拟问题
【发布时间】:2014-06-28 05:07:45
【问题描述】:

我在模拟“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)

【问题讨论】:

    标签: arrays logic simulation


    【解决方案1】:

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

    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;如果 goat 为 3 且 selected 为 1,则将其更改为 2; ETC... 至于为什么您的原始代码不起作用,以 10000 个为一组返回所有东西看起来非常奇怪且难以调试。你的随机数也可以用 randint 来完成,这也会使你的代码更易于阅读。

    【讨论】:

    • 感谢您的反馈!我真的很喜欢你使用对象而不是数组所做的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多