LoginSignup
29
21

モンティ・ホール問題を愚直にやってみる

Last updated at Posted at 2023-10-07

モンティ・ホール問題は理屈を聞いてもわかったような分からないような、感じだったので愚直に1ゲームずつやってみて本当に変更したほうが有利なのかを検証してみました

とりあえず10回やってみることにします

monty.py

import random

def oneTurn(isChange):# 
    #ゲーム一回分を実行する関数
    #   引数:isChange 選択後に交換するかしないか True False
    #   戻値:hit 当たったか外れたか    1:当たり 0:ハズレ

    #当たりの箱(インデックス番号)を用意する
    hitIndex = random.randint(0,2)

    #ユーザーの入力はランダムで
    playerFirstChoice = random.randint(0,2)

    boxLeftIndex=[0,1,2]#残っている箱(司会者が見せる箱の選択肢)

    if playerFirstChoice==hitIndex:#最初の選択がたまたま当たりのとき
        """
        まずは箱を3つ、配列として準備する   boxLeftIndex=[0,1,2]
        例えば3つめの箱(インデックスは2)が当たりとする
        その箱は見せないので除いておく      boxLeftIndex=[0,1]

     次にプレイヤが選択、たまたま2の箱(当たり)を選択したとする 

        この場合、司会者が見せるのは0か1  boxLeftIndex=[0] or boxLeftIndex=[1]
        """
        boxLeftIndex.remove(hitIndex)   #当たりは絶対見せないので除いておく
        r2 = random.randint(0,1)        #見せる箱を乱数で決定
        mcOpenIndex = boxLeftIndex[r2]  #mcOpenIndex:司会者が開示する番号

        #そのあとプレイヤがチェンジするか否か(すでに引数で決定されている)
        if isChange==False:
          finalIndex=playerFirstChoice#変更しないなら最初のまま
        else:
          boxLeftIndex.remove(mcOpenIndex)   #mcの出したハズレを取り除く
          finalIndex=boxLeftIndex[0]

    else:#最初の選択が外れのとき
        """例えば2の箱が当たりとする         boxLeftIndex=[0,1,2]
        当たりは見せないので除いておく        boxLeftIndex=[0,1]
        はずれのプレイヤは1の箱(ハズレ)を選択したので1を除去
        mc(司会者)は0の箱を見せないといけない  boxLeftIndex=[0]
        """
        boxLeftIndex.remove(hitIndex)           #当たりは絶対見せないので除いておく
        boxLeftIndex.remove(playerFirstChoice)  #プレイヤの選択したハズレを除去
        mcOpenIndex = boxLeftIndex[0]           #mcOpenIndex:mcが開示する番号

        #そのあとプレイヤがチェンジするか否か(すでに引数で決定されている)
        if isChange == False:                   #チェンジしないなら
          finalIndex=playerFirstChoice          #  最初のまま
        else:                                   #チェンジする場合
          tmpbox = [0,1,2]                      #  一時的な配列を用意
          tmpbox.remove(mcOpenIndex)            #  mcの開示した番号を除去
          tmpbox.remove(playerFirstChoice)      #  自分が最初に選んだ番号を除去
          finalIndex = tmpbox[0]                #  ファイナルアンサー

    #当たり外れの判定
    if finalIndex == hitIndex:
      hit=1
    else:
      hit=0

    return hit


#===main ==============================
N=10
ct_hit=0
print("==============変更した場合==================")
for i in range(N):
    hit = oneTurn(True)
    ct_hit += hit
print("当たり回数=",ct_hit)    
print("==============変更しない場合==================")
ct_hit=0
for i in range(N):
    hit = oneTurn(False)
    ct_hit += hit
print("当たり回数=",ct_hit)    

結果はこんな感じで
==============変更した場合==================
当たり回数= 5
==============変更しない場合==================
当たり回数= 4

なんだかよくわかりません

回数を増やす

N=100000とした場合は
==============変更した場合==================
当たり回数= 66436
==============変更しない場合==================
当たり回数= 33275
となってたしかに倍の確率になることがわかります

29
21
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
21