アメリカのTV番組 で生まれたという興味深い「モンティ・ホール問題 」。
「3つのうち1つが当たりのくじ引き」で、あなたが1つを選んだ後に司会者がハズレを1つ減らしてくれます。この段階でチェンジ可能な場合「あなたはチェンジしますか?しませんか?」という問題。
パッと聞くと、もはや 2つ となった目の前のくじ、変えようが変えまいが当たる確率は 1/ 2 な気がします。
ではコンピュータでシミュレーション、今回は「こどもOS IchigoLatte JS 」で。
まずは、
var hit = rnd(3);
当たりをセット、このプログラムの意味は以下。
次は、
var chosen = rnd(3);
3つのうち1つを選択。
そしてここでハズレを一つ減らします。
var reduced = rnd(3);
while( (reduced==hit) + (reduced==chosen) ){
reduced = rnd(3);
}
これの意味は、
reduced while( 〇 〇〇 ){ □ □□ } (reduced==hit) + (reduced==chosen) (reducedがhitと等しい) か (reducedがchosenと等しい)
つまり、
「reduced」をランダムに1つ選ぶんだけど「hit」や「chosen」と同じだったらそれは減らしたらいけないので、違うやつになるまで rnd(3) をしまくる。
という感じ。
では今回はチェンジしないバージョンということにして、
if(chosen==hit){ log("HIT!\n"); }else{ log("blank…\n"); }
結果を表示しちゃいましょう。
if( 〇〇〇 ){ □□□ } chosen==hit log( “HIT!\n” ) “HIT!\n” と画面に出す(”\n”は”改行”の意味) else{ △△△ }
こんな感じ。ここまでをまとめると最終的にシミュレーションプログラムは、
var hit = rnd(3);
var chosen = rnd(3);
// reduce one
var reduced = rnd(3);
while( (reduced==hit) + (reduced==chosen) ){
reduced = rnd(3);
}
// show result
if(chosen==hit){
log("HIT!\n");
}else{
log("blank…\n");
}
こんな具合、”vi” でこれを打ち込んで ESCキー でセーブ&Exitしよう。
実行は
lash> ms .
こんな具合、「HIT!」が出れば当たり、「blank…」が出ればハズレ。何度も “ms .” すれば当たったりハズレたりを確認できるね。
さて、1,000回ほどシミュレーションしてみよう。1,000回も “ms .” するのはしんどいので、これもプログラミング。
var count=1000;
while(0 < count){
var hit = rnd(3);
var chosen = rnd(3);
// reduce one
var reduced = rnd(3);
while( (reduced==hit) + (reduced==chosen) ){
reduced = rnd(3);
}
// show result
if(chosen==hit){
log("HIT!\n");
}else{
log("blank...\n");
}
count = count-1;
}
太字の部分を加えました。はじめ “count” を 1,000 にして置いて、”0 < count” な間くり返します。”count” は下の方で “count = count-1″ しているので1ずつ減っていき、”0” になった時点で終了します。
lash> ms .
HIT!
HIT!
blank…
blank…
HIT!
blank…
blank…
:
:
:
実行するとこんな具合、1,000回シミュレーションされ、結果が大量に表示されます。あとはこれを集計すれば、、、でも手ではたいへん。なので集計もプログラミング。
var count=1000;
var hits=0;
while(0 < count){
var hit = rnd(3);
var chosen = rnd(3);
// reduce one
var reduced = rnd(3);
while( (reduced==hit) + (reduced==chosen) ){
reduced = rnd(3);
}
// show result
if(chosen==hit){
hits = hits+1;
}else{
// none
}
count = count-1;
}
log(hits, "\n");
はじめ “hits” を0にして置いて、当たったら “hits = hits+1” で1増やす。1,000回終わったら hits を表示、”\n”は改行の意味。
lash> ms .
319
319回当たりました。
lash> ms .
326
2回目は326。
lash> ms .
350
3回目は350、3回を平均すると331.7回。モンティ・ホール問題で当たる確率は、チェンジしないと33%ほどのようです。つまり、66%ほどはハズレる、言い換えると「チェンジしていれば66%ほどで当たる」という事になります。不思議ですね。
ここで、よくよくソースコードを見ると、
var reduced = rnd(3);
while( (reduced ==hit) + (reduced ==chosen) ){
reduced = rnd(3);
}
この部分、せっかく while まで使って reduced(減らすやつ) を選んでいるのに、
if(chosen==hit){
hits = hits+1;
}else{
// none
}
結果に reduced は利用されていません。つまりこのプログラムで “reduced” は無くても結果に影響しない、あるだけでCPUやメモリを消費する無駄なモノです。
var count=1000;
var hits=0;
while(0 < count){
var hit = rnd(3);
var chosen = rnd(3);
// show result
if(chosen==hit){
hits = hits+1;
}else{
// none
}
count = count-1;
}
log(hits, "\n");
つまりこうですね。このように無駄なモノを取り除くことを「最適化」と呼んだりします。C/C++などの言語ではコンパイラがこれを自動でやってくれますが、今回の IchigoLatte JS はやってくれないのでこのように手動で最適化しました。
lash> ms .
313
実行しても結果は最適化前と同じです。
つまりこの「モンティ・ホール問題」、チェンジしないのであれば「司会者が1つ減らす」という行為は必要ありません。単に3つの中から1つ選ぶので、確率は1/3。
「チェンジしていれば2/3で当たり」をあえてプログラミングしてみましょう。
if(reduced==0){
if(chosen==1) chosen=2;
else chosen=1;
}else{
if(reduced==1){
if(chosen==0) chosen=2;
else chosen=0;
}else{
if(chosen==0) chosen=1;
else chosen=0;
}}
チェンジするプログラムはこんな感じ。
var count=1000;
var hits=0;
while(0 < count){
var hit = rnd(3);
var chosen = rnd(3);
// reduce one
var reduced = rnd(3);
while( (reduced==hit) + (reduced==chosen) ){
reduced = rnd(3);
}
// change chosen
if(reduced==0){
if(chosen==1) chosen=2;
else chosen=1;
}else{
if(reduced==1){
if(chosen==0) chosen=2;
else chosen=0;
}else{
if(chosen==0) chosen=1;
else chosen=0;
}}
// show result
if(chosen==hit){
hits = hits+1;
}else{
// none
}
count = count-1;
}
log(hits, "\n");
これを結果表示の前に入れ込んで、全体はこんな具合。前回と違って reduced が役に立っているので消すことはできませんね。
lash> ms .
693
実行してみるとだいたい 2/3 になっています。ただし、さっきの最適化したプログラムで 2.5秒 だったシミュレーションが、今回は 7.5秒 になりました。元のシミュレーションの方が良いですね。
ひとまず「モンティ・ホール問題」において、「当てたいのであればチェンジはすべき」というのが結論になりそうです。
この問題を知った時、「だったら最初から2つにして選ばせればいいじゃん」って思ってたわけですが、それだと当たる確率は1/2。あえて「3つの時に1つ選ばせて、減らしたあとでチェンジする」という手段を取ることで当たる確率が2/3に上昇するという、にわかに信じ難い くじ引きゲーム。
VIDEO
米村でんじろうサイエンスプロダクションチャンネル でも詳しく説明されています。(でんじろうさん、福井に引っ越してもっと広い実験場で楽しい動画を撮られてはいかがでしょう?)
それでも「えー、ほうとうに?」「いやー、ちがうでしょー」と思う人がいるかも。今回のシミュレーションとは違う意見がある方はご意見聞かせてください。
最初の くじの数 が 1億個 だったら?
.