#define MAX_PLAYERS 16
+enum OutputMode {
+ PROBABILITY_MATRIX = 0,
+ MOST_LIKELY_MATCHING = 1,
+};
+
float match_stddev = 70.0f;
struct player {
int main(int argc, char **argv)
{
int trials = atoi(argv[1]);
+ OutputMode output_mode;
+ int match_player_num = -1, match_position = -1;
+ if (argc >= 3) {
+ match_player_num = atoi(argv[2]);
+ match_position = atoi(argv[3]);
+ output_mode = MOST_LIKELY_MATCHING;
+ } else {
+ output_mode = PROBABILITY_MATRIX;
+ }
+
+ // For most likely matching.
+ bool has_mlm = false;
+ double mlm_likelihood = 0.0f;
+ int mlm_scores[MAX_PLAYERS][MAX_PLAYERS];
if (scanf("%f", &match_stddev) != 1) {
fprintf(stderr, "Could't read match stddev\n");
exit(1);
}
if (ret < 2) {
- rating = 1500.0f;
+ rating = 500.0f;
}
players.push_back(buf);
float mu = drawn_ratings(pl1) - drawn_ratings(pl2);
int score = lrintf(draw_gaussian(mu, match_stddev));
- scores[pl1][pl2] = score;
- scores[pl2][pl1] = -score;
+ if (score >= 0) {
+ scores[pl1][pl2] = score;
+ scores[pl2][pl1] = 0;
+ } else {
+ scores[pl1][pl2] = 0;
+ scores[pl2][pl1] = -score;
+ }
}
}
// order by points and then margin
sort(stats, stats + num_players, highest_ranking());
- for (int j = 0; j < num_players; ++j) {
- ++placements[stats[j].player_index][j];
+
+ if (output_mode == PROBABILITY_MATRIX) {
+ for (int j = 0; j < num_players; ++j) {
+ ++placements[stats[j].player_index][j];
+ }
+ }
+ if (output_mode == MOST_LIKELY_MATCHING) {
+ if (stats[match_position].player_index != match_player_num) {
+ continue;
+ }
+
+ // compute the log-likelihood of this situation (ignoring the constant terms)
+ double llh = 0.0f;
+
+ // strength of all players (ignore the constant terms)
+ for (int p = 0; p < num_players; ++p) {
+ llh -= drawn_normals(p) * drawn_normals(p) * 0.5f;
+ }
+
+ // all the matches
+ for (int pl1 = 0; pl1 < num_players; ++pl1) {
+ for (int pl2 = pl1 + 1; pl2 < num_players; ++pl2) {
+ if (has_scores[pl1][pl2]) {
+ continue;
+ }
+ float mu = drawn_ratings(pl1) - drawn_ratings(pl2);
+ float z = (scores[pl1][pl2] - scores[pl2][pl1] - mu) / match_stddev;
+ llh -= z * z * 0.5f;
+ }
+ }
+
+ if (!has_mlm || llh > mlm_likelihood) {
+ has_mlm = true;
+ mlm_likelihood = llh;
+ memcpy(mlm_scores, scores, sizeof(mlm_scores));
+ }
}
}
- for (int i = 0; i < num_players; ++i) {
- printf("%-15s", players[i].c_str());
- for (int j = 0; j < num_players; ++j) {
- printf(" %5d", placements[i][j]);
+ if (output_mode == PROBABILITY_MATRIX) {
+ for (int i = 0; i < num_players; ++i) {
+ printf("%-15s", players[i].c_str());
+ for (int j = 0; j < num_players; ++j) {
+ printf(" %5d", placements[i][j]);
+ }
+ printf("\n");
+ }
+ }
+ if (output_mode == MOST_LIKELY_MATCHING && has_mlm) {
+ for (int pl1 = 0; pl1 < num_players; ++pl1) {
+ for (int pl2 = pl1 + 1; pl2 < num_players; ++pl2) {
+ if (has_scores[pl1][pl2]) {
+ continue;
+ }
+ printf("%s %s %d\n", players[pl1].c_str(), players[pl2].c_str(), mlm_scores[pl1][pl2] - mlm_scores[pl2][pl1]);
+ }
}
- printf("\n");
}
}