3体問題

日常の数学・物理    ーー それでも地球はまわっている



モンティーホール(シミュレーション)


-マリリンが伝えたかったこと-
モンティーホール問題を ドア10個の例でシミュレーションしてみる

司会者が、ドアを変えてもよいと促したあと
ドアを変更しない場合 :『最初にはずれをひいたらそのままはずれるし、逆に、
ドアを変更する場合  :『最初にはずれをひいたら 100%自動車を選ぶ
 
ことになる。 

変更しない
(最初はずれをひいたら そのままはずれることになる)

変更する
(最初はずれをひいたら 結局、自動車を選ぶことになる)


—決定前:  1回目のドアを決定した—
や  ぎ■
や  ぎ■
自動車

や  ぎ■
や  ぎ■
や  ぎ■
や  ぎ■
や  ぎ■  『とりあえずここ』
や  ぎ■
や  ぎ■

—ドアを開放した後—
『さあ、ドアを変えますか?』

や  ぎ□
や  ぎ□
自動車

や  ぎ□
や  ぎ□
や  ぎ□
や  ぎ□
や  ぎ■←私  『やめようかなあ』
や  ぎ□
や  ぎ□

『変更しない』


や  ぎ□
や  ぎ□
自動車

や  ぎ□
や  ぎ□
や  ぎ□
や  ぎ□
や  ぎ□←私  はずれ!
や  ぎ□
や  ぎ□


—決定前:  1回目のドアを決定した—
や  ぎ■
や  ぎ■
自動車
や  ぎ■
や  ぎ■
や  ぎ■
や  ぎ■
や  ぎ■  『とりあえずここ』
や  ぎ■
や  ぎ■

—ドアを開放した後—
『さあ、ドアを変えますか?』

や  ぎ□
や  ぎ□
自動車
や  ぎ□
や  ぎ□
や  ぎ□
や  ぎ□
や  ぎ■←私  『やめようかなあ』
や  ぎ□
や  ぎ□

『変更する』

や  ぎ□
や  ぎ□
自動車←私  あたり!
や  ぎ□
や  ぎ□
や  ぎ□
や  ぎ□
や  ぎ□(変更前)
や  ぎ□
や  ぎ□

十進BASIC

!モンティーホール問題

DECLARE EXTERNAL FUNCTION  初期並び_自動車
DECLARE EXTERNAL FUNCTION  選択_私
DECLARE EXTERNAL SUB  状態表示0
DECLARE EXTERNAL SUB  状態表示1

DIM door_開閉(100)   !開1閉0

DO
   INPUT PROMPT "door_数(3~20)=":door_数
   IF  (door_数  >2  AND  door_数=<20)  THEN  EXIT  DO    !Door数  3~20戸
LOOP
DO
   INPUT PROMPT "変更YN=1 or 0":変更YN
   IF  (変更YN  =0  OR  変更YN  =1)  THEN  EXIT  DO    !変更YN  =0  or 1
LOOP

!---初期設定---
!  LET door_数=10
LET 試行回数=100
!  LET 変更YN=1          !  変更する 1  変更しない 0    
!---初期設定---

LET Rnd_my=INT(TIME*1000)  !  乱数をさらにかき混ぜる

FOR KKKK=  1  TO  試行回数

   FOR N=1  TO  100         ! 初期化
      LET   door_開閉(N)=0
   NEXT N
    
   LET XXX=初期並び_自動車(door_数,Rnd_my)
   LET YYY=選択_私(door_数,Rnd_my+100)
   PRINT "---------------------------------------------------"
    
   CALL 状態表示0(XXX,YYY,door_数,door_開閉)  !  司会者  ドア開放前   状態印刷
    
   !PRINT   XXX    !初期並び_自動車
   !PRINT   YYY    !選択_私
    
   LET XXX0=XXX  ! XXX   自動車のあるドア
   LET YYY0=YYY  ! YYY0  最初に私が選んだドア
    
    
   DO            ! 司会者(モンティーホール)が私が指したドア以外で  ”自動車でない”ドアを選ぶ  
    
      LET MMM開=モンティホウル開(door_数,Rnd_my+200)
      IF MMM開<>YYY0 AND  MMM開<>XXX0 THEN LET door_開閉(MMM開)=1  ! 「私が選ばず  かつ  自動車でない」  をひらく
       
      LET   開_数=0
      FOR LL= 1  TO door_数
         LET  開_数=  開_数 + door_開閉(LL)
      NEXT LL
      IF (door_数-開_数)=2 THEN  EXIT  DO  ! 2つになるまで開けていく
   LOOP
    
   CALL 状態表示1(XXX,YYY,door_数,door_開閉)  !  モンティードア開放後   状態印刷
    
   IF 変更YN=1  THEN    !  変更するときだけ考える
      DO
         LET YYY=選択_私(door_数,Rnd_my+100)                !  ここは乱数でなくてもよいがあえて乱数とした
         IF  YYY<>YYY0 AND door_開閉(YYY)=0  THEN  EXIT DO  !  過去と違う場所  モンティホールが開かなかったドアを選ぶ
      LOOP  
   END IF
    
   PRINT ""
   IF 変更YN=1  THEN  PRINT "『変更する』"
   IF 変更YN=0  THEN  PRINT "『変更しない』"
    
   PRINT ""
   !   PRINT "◆決定後◆"
    
   FOR LL  =  1 TO  door_数 
      IF XXX=LL  then  
         print  "自動車□";
         IF YYY=LL  THEN
            PRINT "←私";"  あたり!"
         ELSE
            PRINT ""
         END IF
      ELSE
         print  "や  ぎ□";
         IF YYY0=LL AND 変更YN=1   THEN PRINT "←(変更前)";
         IF YYY=LL  THEN
            PRINT "←私";"  はずれ!"
         ELSE
            PRINT ""
         END IF
          
      END IF   
   NEXT LL
    
   IF XXX=YYY  THEN
      LET cnt_Yes=cnt_Yes+1
   END IF
    
   PRINT ""
    
   LET Rnd_my=Rnd_my+1
NEXT KKKK

PRINT "door_数=";door_数
PRINT "あたり数=";cnt_Yes
PRINT  "試行回数=";試行回数
PRINT "あたり数/試行回数=";cnt_Yes/試行回数

END

EXTERNAL SUB  状態表示0(XXX,YYY,door_数,door_開閉())  !  決定前  モンティー前  表示
PRINT "---決定前:  1回目のドアを決定した---"
FOR LL  =  1 TO  door_数 
   IF XXX=LL  then  
      print  "自動車";
      IF door_開閉(LL)=1 THEN PRINT "■";  !全部閉じる
      IF door_開閉(LL)=0 THEN PRINT "■";  !全部閉じる
      IF YYY=LL  THEN
         PRINT "←私  『とりあえずここ』"
      ELSE
         PRINT ""
      END IF
   ELSE
      print  "や  ぎ";
      IF door_開閉(LL)=1 THEN PRINT "■";  !全部閉じる
      IF door_開閉(LL)=0 THEN PRINT "■";  !全部閉じる
      IF YYY=LL  THEN
         PRINT "←私  『とりあえずここ』"
      ELSE
         PRINT ""
      END IF
   END IF   
NEXT LL
END SUB



EXTERNAL SUB  状態表示1(XXX,YYY,door_数,door_開閉())  !  決定前  モンティー後  表示
PRINT ""
PRINT "---司会者がドアを開放した---"
PRINT ""
PRINT "『さあ、ドアを変えますか?』"
PRINT ""

FOR LL  =  1 TO  door_数 
   IF XXX=LL  then  
      print  "自動車";
      IF door_開閉(LL)=1 THEN PRINT "□";
      IF door_開閉(LL)=0 THEN PRINT "■";
      IF YYY=LL  THEN
         PRINT "←私  『やめようかなあ』"
      ELSE
         PRINT ""
      END IF
   ELSE
      print  "や  ぎ";
      IF door_開閉(LL)=1 THEN PRINT "□";
      IF door_開閉(LL)=0 THEN PRINT "■";
      IF YYY=LL  THEN
         PRINT "←私  『やめようかなあ』"
      ELSE
         PRINT ""
      END IF
   END IF   
NEXT LL
END SUB


EXTERNAL FUNCTION  初期並び_自動車(NNN,cnt)
RANDOMIZE 
LET 初期並び_自動車=MOD(INT(RND*100000000*cnt),NNN)+1 
END FUNCTION
 
EXTERNAL FUNCTION  選択_私(NNN,cnt)
RANDOMIZE 
LET 選択_私=MOD(INT(RND*1000000*cnt),NNN)+1 
END FUNCTION
 
EXTERNAL FUNCTION  モンティホウル開(NNN,cnt)  !モンティホールが開いたドア
RANDOMIZE 
LET モンティホウル開=MOD(INT(RND*10000*cnt),NNN)+1 
END FUNCTION