2018年2月5日月曜日

[Pyrhon] コイントスで表か裏が10回連続で出る確率

エレガントな解法、エレファントな解法 〜モンテカルロ法を添えて〜」という山本一成さんのnoteにあったプログラムを実行してみた際のメモです.

問題は
 コインを100回投げて、表か裏が10回連続で出る確率は?
というものです.
これを実際にコイントスをやってみて確かめるという方法です.
具体的には,コンピュータの中で乱数(ランダム)を発生させ,それでコイントスをしていることとするというものです.

pythonでのプログラムは以下のとおりです.

import numpy

def cointoss(try_count, length):
    x = 0
    prev_ret = None
    for _ in range(try_count):

        ret = numpy.random.randint(0, 2)
        if prev_ret == ret:
            x += 1
            if x >= length:
                return True
        else:
            prev_ret = ret
            x = 1
    return False

def monte_carlo(try_count):
    x = 0.0
    y = 0.0
    for _ in range(try_count):
        if cointoss(100, 10):
            x += 1
        y += 1
    return 100.0 * x / y

print("   100 : {0}%".format(monte_carlo(100)))
print("  1000 : {0}%".format(monte_carlo(1000)))
print(" 10000 : {0}%".format(monte_carlo(10000)))

print("100000 : {0}%".format(monte_carlo(100000)))

これをコンパイル,実行してみると以下のようになりました.
$ python cointoss.py
   100 : 9.0%
  1000 : 9.4%
 10000 : 8.91%
100000 : 8.695%

上記の記事の中では,近似解が
       100回: 14.0%
     1000回 : 8.8%
    10000回: 8.89%
  100000回: 8.773%
となっています.
正解は8.669%だそうです.

ちなみに,プログラムの最後の部分に

print(" 1000000 : {0}%".format(monte_carlo(1000000)))
print("10000000 : {0}%".format(monte_carlo(10000000)))

と書き足して,3回実行させてみた結果は以下のとおりです.

(その1)
$ python cointoss.py
     100 : 10.0%
    1000 : 8.4%
   10000 : 8.94%
  100000 : 8.535%
 1000000 : 8.6777%
10000000 : 8.66218%

(その2)
$ python cointoss.py
     100 : 11.0%
    1000 : 7.5%
   10000 : 8.87%
  100000 : 8.634%
 1000000 : 8.6414%
10000000 : 8.67728%

(その3)
$ python cointoss.py
     100 : 6.0%
    1000 : 10.1%
   10000 : 9.0%
  100000 : 8.815%
 1000000 : 8.5956%
10000000 : 8.68189%

0 件のコメント :

コメントを投稿