Pages

2011年8月9日火曜日

モンティ・ホール問題

確率の本を読んでいるとモンティ・ホール問題に出会ったので,暇つぶしにプログラムを作ってみる.

モンティ・ホール問題 ~進行の手順~
①三つの扉が用意される.このうち,一つが当たり.残りの二つがはずれである.
②あなたが一つの扉を選ぶ.
③司会者が残りの二つの扉のうち,はずれの扉を開ける.
④この時点で,あなたに扉を選び直す権限を与えられる.
⑤「あなたは扉を選び直しますか?」

こんな感じの問題.


Javaで作成.
import java.util.Random;

public class MontyHall {

    boolean chengedoor;
    int loopcount;
    int success = 0;
    Random rand= new Random();

    MontyHall(boolean changedoor, int loopcount){
        this.chengedoor = changedoor;
        this.loopcount = loopcount;

        execute();
        printResult();
    }

    private void execute(){
        for(int i=0 ; i<this.loopcount ; i++){
            //答えをセット
            int answerNo = this.rand.nextInt(3);

            //ユーザが選択
            int userNo = this.rand.nextInt(3);

            //司会者が一つ選ぶ(答えの扉以外)
            int obserNo = -1;
            if(answerNo == userNo){
                int r = this.rand.nextInt(2);
                switch(answerNo){
                case 0:
                    if(r==0) obserNo=1;
                    else obserNo=2;
                    break;
                case 1:
                    if(r==0) obserNo=0;
                    else obserNo=2;
                    break;
                case 2:
                    if(r==0) obserNo=0;
                    else obserNo=1;
                    break;
                }
            }
            else{
                obserNo = 3-(answerNo+userNo);
            }

            //回答チェンジ!
            if(this.chengedoor)
                userNo = 3-(userNo+obserNo);

            // 答え合わせ
            if(userNo == answerNo)
                this.success++;
        }
    }

    private void printResult() {
        String type = "";
        double sucper = (this.success / (double)this.loopcount)*100;
        if(this.chengedoor){
            type="Change! ";
        }
        else{
            type="NoChange";
        }
        System.out.println(type+":"+sucper+"%");
    }

    public static void main(String args[]){
        int loopcount = 100000;
        new MontyHall(true,loopcount);
        new MontyHall(false,loopcount);
    }

}

上記の通り,10万回試行してみる.
結果は…

Change! :66.982%
NoChange:33.283%

この通り.
当たりの扉を選びたいならChange!