LoginSignup
5
6

More than 5 years have passed since last update.

「モンティ・ホール問題」をシミュレートする

Last updated at Posted at 2018-04-18

rubyでモンティホール問題に挑戦」の記事を見て、自分なりにやってみたくなりました。ここでは Go でやってみます。

「モンティ・ホール問題」とは

三つの扉があり、その向こうのひとつにだけ当たりがあります。
 
挑戦者はまず三つの扉の中からひとつを選びます。
司会者(モンティ・ホール)は当たりの扉を知っています。そして二つあるハズレの扉のひとつ(挑戦者が選択していないそれ)を開けます。
挑戦者はそこで前に選んだ扉をもういちどそのまま選択してもよいし、二つの扉の別の方を選択してもよい。
 
さて、挑戦者はここで扉をもうひとつのそれに替えた方がよいのか、そのままにした方がよいのか、それともいずれでも当たる確率は一緒なのか。
どうなのでしょうか?

実際のところは?

先に答えを言っておくと、これは「扉を替えた方」が当たる確率は高くなるのです。扉を替えない場合、当たる確率は 1/3 で、扉を替えると 2/3 になります1

不思議ですか? ただ扉を開けただけなのに?

シミュレートしてみる

コードはこんな具合になりました。

monty_hall_problem.go
package main
import "fmt"
import "math/rand"
import "time"

const n = 1000000

//一回の試行
func trial(is_reselection bool) (result bool) {
    doors := [3]bool{true, false, false}
    select_of_challenger := rand.Intn(3)

    if is_reselection {
        remained_doors := doors[0:2]
        reselect_of_challenger := 0
        if select_of_challenger == 0 { reselect_of_challenger = 1 }
        result = remained_doors[reselect_of_challenger]
    } else {
        result = doors[select_of_challenger]
    }
    return
}

//n回試行して確率の計算
func calc(is_reselection bool) float32 {
    co := 0
    for i := 0; i < n; i++ {
        if trial(is_reselection) { co++ }
    }
    return float32(co) / float32(n)
}

func main() {
    rand.Seed(time.Now().UnixNano())

    //扉を替えない場合
    fmt.Println(calc(false))    //=>0.333683
    //扉を替える場合
    fmt.Println(calc(true))     //=>0.666448
}

確かにそうなります。

説明が必要でしょう。まず、扉 0, 1, 2 があって、当たりは必ず扉 0 にあるとします。挑戦者は何も知らないので、この仮定で問題ありません。これがdoors := [3]bool{true, false, false}で表されます。
挑戦者が最初にどれを選んでも、モンティがひとつ開けて(それは挑戦者の選んだ扉ではなく、また当たりでもありません)残った扉は「当たり、ハズレ」の二つになります。とにかくモンティは、ハズレの扉を開けるしかないのですから。それがremained_doors := doors[0:2]の表わすところです。

あとはさほど問題はないと思います。

なお、これのRuby版がここにあります。

追記

何だか不思議ですね。最初はおもいっ切りまちがえていました2


  1. まちがえやすいのは、扉を替えると当たる確率が 1/2 となる、というものです。正しくは 2/3 なのです。Wikipediaによれば、これはアメリカで実際に大論争になったそうです。 

  2. 2/3 というのが納得できない人へ。上のコードでreselect_of_challengerの値が 0 になるのはselect_of_challengerの値が 1 と 2 の場合であることに注意するとよいかも知れません。対してreselect_of_challengerの値が 1 になるのはselect_of_challengerの値が 0 の場合だけです。 

5
6
0

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
5
6