2010年3月24日水曜日

封筒の話(続き)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
r[3]/r[2]を計算するようにしてみた。あとそれからn=20までを対象にした。それ以上は外れ値として無視(頻度が低いため、十分な試行数がないから)
しかし2の時、交換すると減るという変な結果が出てるな。

[nori@shinano]~/Desktop/study/python/hack% python two2envelopes.py 100000
[1, 16715, 16715, 33430, 0] 2.0 0.0
[2, 19473, 38946, 27669, 16741] 0.710445231859 0.85970317876
[4, 5991, 23964, 31428, 2750] 1.3114672008 0.459021866133
[8, 7006, 56048, 73312, 3232] 1.30802169569 0.46131886954
[16, 8180, 130880, 172504, 3719] 1.31803178484 0.454645476773
[32, 6796, 217472, 222064, 4435] 1.02111536198 0.652589758682
[64, 4601, 294464, 364864, 2334] 1.2390784612 0.507281025864
[128, 4500, 576000, 697152, 2369] 1.21033333333 0.526444444444
[256, 4016, 1028096, 1234432, 2140] 1.20069721116 0.532868525896
[512, 3305, 1692160, 1935104, 1887] 1.14357034796 0.570953101362
[1024, 2764, 2830336, 3424256, 1456] 1.20984081042 0.526772793054
[2048, 2332, 4775936, 5721088, 1247] 1.19789879931 0.534734133791
[4096, 2095, 8581120, 10489856, 1086] 1.22243436754 0.518377088305
[8192, 1740, 14254080, 16429056, 983] 1.1525862069 0.564942528736
[16384, 1504, 24641536, 30138368, 779] 1.22307180851 0.51795212766
[32768, 1294, 42401792, 51724288, 673] 1.21986089645 0.520092735703
[65536, 1133, 74252288, 88834048, 607] 1.19638128861 0.53574580759
[131072, 984, 128974848, 148832256, 555] 1.15396341463 0.564024390244
[262144, 763, 200015872, 238026752, 412] 1.19003931848 0.53997378768
[524288, 682, 357564416, 438304768, 352] 1.22580645161 0.516129032258

どういう訳だか、2が出たときに、大きな数値が入っている封筒を高確率で先に開けてしまう。
import sys
import random

class Die:
  def roll(self):
    r = random.randint(1, 6)
    assert r > 0
    assert r < 7
    return r
  def odd(self):
    return bool(random.randint(0, 1))

die = Die()

class Envelope:
  def __init__(self):
    r = die.roll()
    n = 0
    while r < 5:
      n += r
      r = die.roll()
    self.values = (1 << n, 1 << (n + 1))

  def open(self):
    self.first_opend = die.odd()
    return self.values[self.first_opend]

  def swap(self):
    return self.values[not self.first_opend]
    

def experiment(t):
  result = {}
  for i in range(t):
    e = Envelope()
    v = e.open()
    s = e.swap()
    r = result.get(v, None)
    if r is None:
      r = [0, 0, 0, 0] #occurence, none-swap case, swap case, respectivly
    r[0] += 1
    r[1] += v
    r[2] += s
    if e.first_opend:
      r[3] += 1
    result[v] = r
  return result

r = experiment(int(sys.argv[1]))

xs = [[i, r[i][0], r[i][1], r[i][2], r[i][3]] for i in r]
xs.sort(key=lambda x: x[0])

total = ['sum', 0, 0, 0]
for i in range(20):
  r=xs[i]
  total[1] += r[1]
  total[2] += r[2]
  total[3] += r[3]
  print r, 1.0*r[3]/r[2], 1.0*r[4]/r[1]
print total

1 件のコメント:

spbackgammon さんのコメント...
このコメントは投稿者によって削除されました。