今回はあの有名な
クイズ番組の問題のシミュレーションです。


解説はこちら


 
モンティホール問題

3つのドアの中に景品の車が一つ有り
プレイヤーは1つのドアを選択できる
3door

プレイヤーがドアを選択した後、司会者モンティーは
そのドア以外のハズレのドアを開く
monty2

最後にプレイヤーはドアを変えるか
そのままかを選ぶ事が出来る


プレーヤーが1つのドアを選択したあと
外れのドアが1つ開放される

残り2枚の当たりの確率は直感的には
それぞれ 50% になるように思えるが
はたしてそれは正しいだろうか...





解説


開けるドアを
変える場合 と 変えない場合
勝率がどうなるのかを計測します。


シミュレーションコードはこちら
import random

def monty_hall_simulation(num_doors=3, num_trials=10000):
    switch_wins,stay_wins = 0,0

    for _ in range(num_trials):
        # 車を隠すドアをランダムに選ぶ
        doors = ['goat'] * (num_doors - 1) + ['car']
        random.shuffle(doors)
        car_index = doors.index('car')

        # プレイヤーが最初に選ぶドアをランダムに選ぶ
        player_choice = random.randint(0, num_doors - 1)

        # モンティが開けるドアを決定する(車とプレイヤーの選択以外)
        monty_choices = [i for i in range(num_doors) if i != player_choice and i != car_index]
        monty_opened = random.sample(monty_choices, num_doors-2)

        # プレイヤーがドアを変更する場合の勝敗
        switch_choice = next(i for i in range(num_doors) if i != player_choice and i not in monty_opened)
        if doors[switch_choice] == "car":
            switch_wins += 1

        # プレイヤーがドアを変更しない場合の勝敗
        if doors[player_choice] == "car":
            stay_wins += 1

    print(f"スイッチした場合の勝率: {switch_wins / num_trials * 100:.4f}%")
    print(f"スイッチしなかった場合の勝率: {stay_wins / num_trials * 100:.4f}%")

# シミュレーション実行
num_doors = 3
num_trials = 10000
monty_hall_simulation(num_doors=num_doors, num_trials=num_trials)
スイッチした場合の勝率: 67.1900%
スイッチしなかった場合の勝率: 32.8100%


この場合
開けるドアを変えた場合は 3分の2
変えない場合は3分の1
の確率で景品を得る事ができます。

つまり、開くドアを変えた方がお得で
約67%の確率で当たりを引けます。

残るのが2個のドアだから50%の確率というのは
まやかしでした。

ちなみにドアの数が増えれば増えるほど
ドアを変えた方が勝率は高くなります。

こんな感じで、直感的に迷う問題でも
プログラムであればシミュレーション出来るので
正しい答えを導き出せる手助けになります。

色々試してみてください
それでは。