こちらはモンティ・ホール問題より有名だと思う。
ある監獄にA、B、Cという3人の囚人がいて、それぞれ独房に入れられている。罪状はいずれも似たりよったりで、近々3人まとめて処刑される予定になっている。ところが恩赦が出て3人のうち1人だけ助かることになったという。誰が恩赦になるかは明かされておらず、それぞれの囚人が「私は助かるのか?」と聞いても看守は答えない。
囚人Aは一計を案じ、看守に向かってこう頼んだ。「私以外の2人のうち少なくとも1人は死刑になるはずだ。その者の名前が知りたい。私のことじゃないんだから教えてくれてもよいだろう?」すると看守は「Bは死刑になる」と教えてくれた。それを聞いた囚人Aは「これで助かる確率が1/3から1/2に上がった」とひそかに喜んだ。果たして囚人Aが喜んだのは正しいか?
まず「Bが死刑になる確率」と「Bが死刑になることを知る確率」が別の物だと気がつくことが大事。通常は「Cが恩赦のとき、Bが死刑になることを知る確率」と「Aが恩赦のとき、Bが死刑になることを知る確率」は同じと考えるべき。しかし、この問題文のような質問の仕方をしてしまうと、「Cが恩赦のとき、Bが死刑になることを知る確率」は1であり、「Aが恩赦のとき、Bが死刑になることを知る確率」は1/2であって、ズレが起こってしまう。
この説明でも怪しいと思う人は、やっぱりシミュレーションして試すとよい。
import scala.util.Random._ val A = 0 val B = 1 val C = 2 def playRole(keeperDecision: Array[Boolean] => Boolean): (Boolean, Boolean) = { val whoAlives = nextInt(3) val isDeath: Array[Boolean] = (0 to 2).map((x: Int) => x != whoAlives).toArray val hearBsDeath: Boolean = keeperDecision(isDeath) (hearBsDeath, isDeath(A)) } def whichIsDeath(isDeath: Array[Boolean]) = { if (! isDeath(C)) true else if (! isDeath(B)) false else nextBoolean() } val leakRate: Double = 0.8 def withNoAssumption(isDeath: Array[Boolean]) = if (isDeath(B) && nextDouble() < leakRate) true else false def statistics(keeperDecision: Array[Boolean] => Boolean): Double = { val results = (1 to 10000).map(_ => playRole(keeperDecision)).toList val resultsKnowOfB = results.filter(_._1) val numOfDead = resultsKnowOfB.count(_._2) numOfDead.toDouble / resultsKnowOfB.length.toDouble * 100 } println("normal situation: %.2f %%" format statistics(withNoAssumption)) println("ask which is death: %.2f %%" format statistics(whichIsDeath))
結果はほぼ理論値通りで、何も仮定しないと死刑となる確率は1/2になるが、この問題の仮定の場合は死刑となる確率は2/3のまま変化しない。
normal situation: 49.51 % ask which is death: 66.85 %