添付ファイル 'rate.cpp'
ダウンロード 1 #include <iostream>
2 #include <vector>
3 #include <map>
4 #include <cmath>
5 #include <cstdlib>
6 #include <sstream>
7 #include <algorithm>
8 #include <cmath>
9 using namespace std;
10
11 #define DISPERSION_CORRECTION 7.5
12
13 // ---------- library begin ----------
14
15 vector<string> split(string str, char delim)
16 {
17 vector<string> ret;
18 for(string::size_type pos = str.find(delim); pos != string::npos; pos = str.find(delim))
19 {
20 ret.push_back(str.substr(0, pos));
21 str = str.substr(pos+1);
22 }
23 if(str.length() > 0)
24 {
25 ret.push_back(str);
26 }
27 return ret;
28 }
29
30 // ---------- library end ----------
31
32 // ---------- structures begin ----------
33
34 struct Player
35 {
36 static map<string, Player> data;
37 string name;
38 double rate;
39 double volatility;
40 int playcount;
41
42 Player() { Player(""); }
43 Player(string name) : name(name), rate(1500), volatility(535*DISPERSION_CORRECTION), playcount(0) {}
44
45 bool operator<(const Player& a) const
46 { return rate > a.rate; }
47 };
48 map<string, Player> Player::data;
49
50 struct Score
51 {
52 string name;
53 double rank, point;
54 Score(vector<string>& args)
55 {
56 name = args[3];
57 if(!Player::data.count(name))
58 Player::data.insert(make_pair(name, Player(name)));
59 stringstream ss;
60 ss << args[4] << " " << args[5];
61 ss >> rank >> point;
62 }
63 Player& player() { return Player::data[name]; }
64 };
65
66 struct Game
67 {
68 int id;
69 string date, set;
70 vector<Score> scores;
71 Game(int id) : id(id) {}
72 void add(vector<string>& args)
73 {
74 date = args[1];
75 set = args[2];
76 scores.push_back(Score(args));
77 }
78 };
79
80 struct Games : vector<Game>
81 {
82 void add(vector<string> args)
83 {
84 int id;
85 stringstream ss;
86 ss << args[0];
87 ss >> id;
88 while(this->size() < id)
89 this->push_back(Game(this->size() + 1));
90 (*this)[id-1].add(args);
91 }
92
93 void calc(int offset = 0)
94 {
95 for(int i = offset; i < this->size(); i++)
96 {
97 Game& game = (*this)[i];
98 int n = game.scores.size();
99
100 // AveRating
101 double AveRating = 0;
102 for(int j = 0; j < n; j++)
103 AveRating += game.scores[j].player().rate;
104 AveRating /= game.scores.size();
105
106 // CF
107 double CF, CF_vol = 0, CF_rate = 0;
108 for(int j = 0; j < n; j++)
109 {
110 Player& p = game.scores[j].player();
111 CF_vol += p.volatility * p.volatility;
112 CF_rate += (p.rate - AveRating) * (p.rate - AveRating);
113 }
114 CF = sqrt(CF_vol / n + CF_rate / (n-1));
115
116 // ERank EPref APref etc..
117 for(int j = 0; j < n; j++)
118 {
119 Score& s = game.scores[j];
120 Player& p = s.player();
121
122 double erank = 0.5, epref, apref, prefas, weight, cap, new_rate, new_vol;
123 for(int k = 0; k < n; k++)
124 erank += wp(game.scores[k].player(), p);
125 epref = - probit((erank - 0.5) / n);
126 apref = - probit((s.rank - 0.5) / n);
127 prefas = p.rate + CF * (apref - epref);
128 weight = 1 / (1 - (0.42/DISPERSION_CORRECTION / (p.playcount + 1) + 0.18/DISPERSION_CORRECTION)) - 1;
129 cap = 150 + 1500 / (p.playcount + 2);
130 new_rate = (p.rate + weight * prefas) / (1 + weight);
131 new_vol = sqrt((new_rate - p.rate)*(new_rate - p.rate) / weight + p.volatility * p.volatility / (weight + 1));
132 p.rate = new_rate;
133 p.volatility = new_vol;
134 p.playcount++;
135 }
136 }
137 }
138
139 double erfinv(double x)
140 {
141 double r = 0;
142 double a[] = { 1, 1.0/12, 7.0/480, 127.0/40320, 4369.0/5806080, 34807.0/182476800 };
143 for(int i = 0; i < 6; i++)
144 r += pow(M_PI, i) * a[i] * pow(x, i*2+1);
145 return sqrt(M_PI) * r / 2;
146 }
147 double wp(Player p1, Player p2)
148 {
149 double a = (p1.rate - p2.rate) / sqrt(2*(p1.volatility * p1.volatility + p2.volatility * p2.volatility));
150 return (erf(a) + 1) / 2;
151 }
152 double probit(double x)
153 {
154 return sqrt(2) * erfinv(2*x - 1);
155 }
156 };
157
158 // ---------- structures end ----------
159
160 int main()
161 {
162 string str;
163 getline(cin, str); // ignore header line;
164
165 Games games;
166 while(getline(cin, str))
167 games.add(split(str, ','));
168
169 games.calc();
170
171 vector<Player> players;
172 for(map<string,Player>::iterator it = Player::data.begin(); it != Player::data.end(); ++it)
173 players.push_back(it->second);
174 sort(players.begin(), players.end());
175 for(int i = 0; i < players.size(); i++)
176 cout << players[i].name << "\t" << round(players[i].rate) << endl;
177 }
添付ファイル
添付ファイルを参照するには、(下のファイル一覧にあるように)attachment:filenameと記述します。 [get]リンクのURLは変更される可能性が高いので、利用しないでください。- [ダウンロード | 表示] (2011-05-16 12:09:44, 10.8 KB) [[attachment:123_all.png]]
- [ダウンロード | 表示] (2011-05-15 19:54:23, 4.0 KB) [[attachment:rate.cpp]]
- [ダウンロード | 表示] (2011-07-15 21:14:31, 4.9 KB) [[attachment:rate.js]]
ファイルを添付する権限がありません。