Line 1: Error: Invalid Blog('by Esehara' )

または私は如何にして心配するのを止めてバグを愛するようになったか

>> Zanmemo

あと何かあれは 「esehara あっと じーめーる」 か @esehara まで

表か裏のどちらかが3連続出るかどうか賭けをしたゲームの場合、何回投げたら公平なのだろうか

今日の風景

f:id:nisemono_san:20160917145522j:plain

端的に説明すると、これは暴力革命を再現したものです。

はじめに

世の中には、直観に反して「ありえそうもないこと」が案外「ありえそう」であることがある。例えば、このブログで以前に紹介した誕生日のパラドックスがそれに当たる。その詳細は上のリンクから飛んでもらうとして、他にも、その類のものがある。

コインを投げて表か裏かのどちらかが、3連続出るかどうかを賭けるゲームを考えてみよう。このとき、何回にしたら公平だろうか。直感的には、3連続というのはなかなかありえそうにもない数であるので、公平なゲームにするためには、7回くらい必要なのではないか、と思う人もいるかもしれない。しかし、7回にした場合、確率的に67.1%の可能性で、3回連続で同じ面が出る。なので、もし7回投げるとした場合、3回連続出るとして賭けるほうが有利なのだ。

組みあわせを考える

しかし、この結論では釈然としない。そこで、ちゃんと組みあわせを考えてみることにする。とはいえ、最初に7回から数えると、投げたときに起こりうる組みあわせの総数は128種類になる。128種類なら、数えられないことは無いけれども、やはり少ない回数から考えていったほうがいいと思う。

まず最初に3回投げたときの場合を考えてみよう。3回の場合、2の3乗なので、8通りの組みあわせが考えられる。このとき、表と裏のどちらかが3連続で出る確率は、3回とも同じ面が出ればいいわけだから、2通り。とすると、2/8、つまり1/4の確率で3連続出ると考えることができる。

同じく4回の場合を考えてみよう。とりあえず3連続出る場合のパターンを数えあげてみると、次のようになるはずだ。ちなみに、一々裏と表と書くのは面倒なので、0と1で表記してある。

[0, 0, 0, 0]
[1, 1, 1, 1]
[0, 0, 0, 1]
[1, 0, 0, 0]
[1, 1, 1, 0]
[0, 1, 1, 1]

この6通りが考えられる。当然、4回の場合には16通りなので、6/16、つまり3/8が考えられる。

フィボナッチみたいに計算する

とはいえ、このように数えあげていくのは、あまりにも非効率的であることは間違いない。実は、3連続にならない組みあわせの数はある公式によって導きだすことができる。

まず、最初にコインを投げる回数をNとする。このとき、3連続ではない組みあわせのことをg_Nとした場合、下の式で算出することができる。

 { g_N = g_{N-1} + g_{N-2} }

この式はフィボナッチ数を求める数と非常に良く似ている。念のため、フィボナッチ数を求める公式は次のようになる(このとき、任意の順番のフィボナッチ数をiとしよう)。

 i_n = i_{n-1} + i_{n-2}

ただし、フィボナッチ数の場合、nが1と2の場合は、n-2に該当するものが存在しないので、1ということになるわけだが、ではこのコイン投げの場合においてはどうなるのかを考えないといけない。

そこで、愚直に1回投げたときに、コインで3回同じ面が出る場合を考えてみよう。とはいえ、書いていて馬鹿馬鹿しいというか、あたりまえだが、そんな組みあわせは存在しない(どうやって1回投げて3回の面を出すというのか)。なので、この場合は2つの組みあわせが、3回連続しない組みあわせとなる。さて、同様に2回投げる場合も同じようにすると4つの組みあわせが、3回連続しない組みあわせとなる。

さて、賢明な読者であるならば、気がついているように、この1回目の2通りと、2回目の4通りを組みあわせると、3回目の6通り(8 - 2)が導きだせる。念のため、4回目も考えてみると、4 + 6 = 16 - 6となる。この具体的 な証明は、実際のところ不明なので、知っている人がいれば教えて頂ければ、と思う。

コードで検証してみる

とはいえ、実際にそういう風になっていると言われても、実際に確率を求めるのがいいだろう、というわけで、さっそく確率を求めるようなコードを書くことにした。

class CoinTossGame
  attr_accessor :win

  def initialize(times)
    @memory_toss = nil
    @win = false
    @succession = 1
    @times = times
  end

  def toss
    result = Random.rand(0..1)
    if result != @memory_toss
      @memory_toss = result
      @succession = 1
    else
      @succession += 1
    end

    if @succession > 2
      @win = true
    end
  end

  def run
    1.upto(@times) do
      toss
    end
  end
end

3.upto(10) do |times| 
  point = 0
  1.upto(10000) do
    game = CoinTossGame.new(times)
    game.run
    point += 1 if game.win
  end
  puts "#{times} TOSS GAME POINT: #{point}"
end

ログは以下の通りである:

3 TOSS GAME POINT: 2493
4 TOSS GAME POINT: 3752
5 TOSS GAME POINT: 5067
6 TOSS GAME POINT: 5872
7 TOSS GAME POINT: 6755
8 TOSS GAME POINT: 7304
9 TOSS GAME POINT: 7836
10 TOSS GAME POINT: 8276

だいたい、推測していた確率になっている。

まとめ

というわけで、だいたい公平になるのは5回投げるのが、賭けとしては一番いいということになる。もし、賭けに有利にしたければ、6回以上を提案すればいいということになる。

数字の国のミステリー (新潮文庫)

数字の国のミステリー (新潮文庫)