蒙蒂霍尔模拟不按预期工作

时间:2017-06-18 19:52:41

标签: python python-3.x simulation python-3.6

我一直在努力解决Python中的if statement以便进行编码,这就是我尝试随机化所有内容的原因。问题是:我遇到了一些麻烦。因为你们大多数人可能都知道monty问题应该表明改变门的胜率(66%)高于留在选定的门(33%)。出于一些奇怪的原因,虽然我的模拟显示两种情况下33%的胜率但我不确定为什么。

以下是代码:

TRUE

我做错了什么?我非常感谢所有的帮助!提前谢谢!

2 个答案:

答案 0 :(得分:1)

ChangeRandom = 0
while gameDoors[ChangeRandom] == gameDoors[inputUser]:
    ChangeRandom = randint(0,2)

这不符合你的想法。不检查ChangeRandom门是否与inputUser门相同,而是检查ChangeRandom门和inputUser门是否具有相同的值 - 即说他们要么都是赢家,要么都是输家。

那就是说,这甚至都不是你想做的。你想要做的是找到一个不是用户输入的门,这是一个失败者的门,然后切换到不是用户输入的OTHER。这可以通过对代码的最小更改来实现:

other_wrong_door = next(c for c, v in enumerate(gameDoors) if v != 0 and c != inputUser)
new_door = next(c for c, _ in enumerate(gameDoors) if c != inputUser and c != other_wrong_door)

但老实说,这值得重新审视你的代码结构。给我几分钟的工作时间,我会编辑这个答案,让你知道我是如何实现的。

import random

DOORS = [1, 0, 0]

def runonce(switch=False):
    user_choice = random.choice(DOORS)
    if user_choice == 1:
        # immediate winner
        if switch:
            # if you won before and switch doors, you must lose now
            return False
        else:
            new_doors = [0, 0]  # remove the user-selected winner
            new_doors = [0]     # remove another loser
            return bool(random.choice(new_doors))
            # of course, this is always `0`, but
            # sometimes it helps to show it. In production you
            # wouldn't bother writing the extra lines and just return False
    else:
        if switch:
            new_doors = [1, 0]  # remove the user-selected loser
            new_doors = [1]     # remove another loser
            return bool(random.choice(new_doors))
            # as above: this is always True, but....
        else:
            return False  # if you lost before and don't switch, well, you lost.

num_trials = int(input("How many trials?"))
no_switch_raw = [run_once(switch=False) for _ in range(num_trials)]
switch_raw = [run_once(switch=True) for _ in range(num_trials)]

no_switch_wins = sum(1 for r in no_switch_raw if r)
switch_wins = sum(1 for r in switch_raw if r)

no_switch_prob = no_switch_wins / num_trials * 100.0
switch_prob = switch_wins / num_trials * 100.0

print( "         WINS    LOSSES   %\n"
      f"SWITCH:  {switch_wins:>4}    {num_trials-switch_wins:>6}  {switch_prob:.02f}\n"
      f"NOSWITCH:{no_switch_wins:>4}    {num_trials-no_switch_wins:>6}  {no_switch_prob:.02f}")

答案 1 :(得分:0)

你已经弄错了问题的机制,所以你得到了错误的结果。我已经重写了选择机制,但是我将用户输入内容留给你,以便你可以继续学习python。这是解决问题的众多方法之一,但希望它向您展示一些内容。

def get_choices():
    valid_choices = [0, 1, 2] # these are the values for a valid sample
    shuffle(valid_choices)    # now randomly shuffle that list
    return valid_choices      # return the shuffled list

def get_door(user_choice):
    return user_choice.index(0)


def monty_sim(n, kind):
    """

    :param n: number of runs in this simulation
    :param kind: whether to change the door or not, 0 - don't change, 1 = change door
    :return: (win_rate, 1 - win_rate)
    """
    wins = 0
    for i in range(0, n):
        game_doors = get_choices()
        user_choice = get_door(get_choices()) # use the same method and find user door choice
        # so there are two branches.
        # In both, a door with a goat (game_door = 1) is chosen, which reduce the result to
        # a choice between two doors, rather than 3.
        if kind == 0:
            if user_choice == game_doors.index(0):
                wins += 1
        elif kind == 1:
            # so now, the user chooses to change the door
            if user_choice != game_doors.index(0):
                wins += 1
            # Because the original choice wasn't the right one, then the new
            # must be correct because the host already chose the other wrong one.

    win_rate = (wins / n) * 100
    return win_rate, 100 - win_rate


if __name__ == '__main__':
    n = 1000
    kind = 1
    wins, loses = monty_sim(n, kind)
    print(f'In a simulation of {n} experiments, of type {kind} user won {wins:02f} of the time, lost {loses:02f} of the time')