2011年3月4日金曜日

リーグ戦による選抜

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
JBL rating 1200が1000のなかで25pt matchで一人選抜する場合をモンテカルロしてみた結果。
試行回数は1サイズあたり10000.

from random import random
from bglib.stat.rating import  winning_chance

'''
one 1200.0 in  999 1000.0 league
'''


class League:
  def __init__(self, ratings):
    self.result = dict()
    self.size = len(ratings)
    self.ratings = ratings

  def report(self, i, j, r):
    assert i in range(self.size)
    assert j in range(self.size)
    assert isinstance(r, bool)
    self.result.update({(i, j):int(r)})
    self.result.update({(j, i):int(not r)})

  def find_winner(self):
    winner = 0
    winners_pt = 0
    for i in range(self.size):
      pt = 0
      for j in range(self.size):
        if i==j:
          continue
        pt += self.result[(i, j)]
      if pt >= winners_pt:
        winner = i
        winners_pt = pt
    return winner, winners_pt


  def run(self):
    for i, x in enumerate(self.ratings):
      for j in range(i + 1, self.size):
        y = self.ratings[j]
        wc = winning_chance(x, y, 25)
        assert x >= y
        self.report(i, j, wc > random())

def simulate(sizer):
  N = 10000
  count = 0
  for trial in range(N):
    league = League((1200.0,)+(1000.0,)*sizer)
    league.run()
    w = league.find_winner()
    if w[0] == 0:
      count+=1
  print sizer, count

#for sizer in range(1, 100):
simulate(100)
サイズ(1000の人の人数)は1から20まで。
結果は10000回あたり1200が選抜された回数。

数字を眺めた感覚としては+-50くらいの精度はありそうですね。
1 7615
2 5901
3 4362
4 4313
5 4449
6 4361
7 4468
8 4685
9 4800
10 4866
11 5079
12 5197
13 5263
14 5572
15 5680
16 5838
17 5929
18 6144
19 6267
20 6427

100人いる場合は995回 out of 1000回だった。1000人はやるかちなさそう。
次の結果の試行回数は1000回
15 569
20 634
25 701
30 786
35 809
40 875
45 884
50 920

0 件のコメント: