Skip to content

Commit 5c7a8aa

Browse files
committed
Fix infinite rating bug
1 parent 52427ec commit 5c7a8aa

12 files changed

+550
-544
lines changed

openskill/models/weng_lin/bradley_terry_full.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,15 +1069,15 @@ def _calculate_rankings(
10691069
return []
10701070

10711071
if ranks:
1072-
team_scores = [ranks[i] or i for i, _ in enumerate(game)]
1072+
team_scores = []
1073+
for index, _ in enumerate(game):
1074+
team_scores.append(ranks[index] or index)
10731075
else:
10741076
team_scores = [i for i, _ in enumerate(game)]
10751077

1076-
output_ranks: dict[int, float] = {}
1077-
s = 0
1078-
for index, value in enumerate(team_scores):
1079-
if index > 0:
1080-
if team_scores[index - 1] < team_scores[index]:
1081-
s = index
1082-
output_ranks[index] = s
1083-
return list(output_ranks.values())
1078+
sorted_scores = sorted(team_scores)
1079+
rank_map: dict[float, int] = {}
1080+
for index, value in enumerate(sorted_scores):
1081+
if value not in rank_map:
1082+
rank_map[value] = index
1083+
return [rank_map[v] for v in team_scores]

openskill/models/weng_lin/bradley_terry_part.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,15 +1065,15 @@ def _calculate_rankings(
10651065
return []
10661066

10671067
if ranks:
1068-
team_scores = [ranks[i] or i for i, _ in enumerate(game)]
1068+
team_scores = []
1069+
for index, _ in enumerate(game):
1070+
team_scores.append(ranks[index] or index)
10691071
else:
10701072
team_scores = [i for i, _ in enumerate(game)]
10711073

1072-
output_ranks: dict[int, float] = {}
1073-
s = 0
1074-
for index, value in enumerate(team_scores):
1075-
if index > 0:
1076-
if team_scores[index - 1] < team_scores[index]:
1077-
s = index
1078-
output_ranks[index] = s
1079-
return list(output_ranks.values())
1074+
sorted_scores = sorted(team_scores)
1075+
rank_map: dict[float, int] = {}
1076+
for index, value in enumerate(sorted_scores):
1077+
if value not in rank_map:
1078+
rank_map[value] = index
1079+
return [rank_map[v] for v in team_scores]

openskill/models/weng_lin/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def _sorter(
4444
unsorted_matrix = _matrix_transpose(matrix)
4545
if unsorted_matrix:
4646
zipped_matrix = list(zip(unsorted_matrix[0], unsorted_matrix[1]))
47-
zipped_matrix.sort(key=_pick_zeroth_index)
47+
zipped_matrix = sorted(zipped_matrix, key=_pick_zeroth_index)
4848
sorted_matrix = [x for _, x in zipped_matrix]
4949
return [x for x, _ in sorted_matrix], [x for _, x in sorted_matrix]
5050
else:

openskill/models/weng_lin/plackett_luce.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,11 @@ def _sum_q(
744744
)
745745
comparison_count += 1
746746

747-
adjusted_mu += margin_adjustment / comparison_count
747+
adjusted_mu += (
748+
(margin_adjustment / comparison_count)
749+
if comparison_count
750+
else margin_adjustment
751+
)
748752

749753
summed = math.exp(adjusted_mu / c)
750754
for q, team_q in enumerate(team_ratings):
@@ -830,7 +834,11 @@ def _compute(
830834
)
831835
comparison_count += 1
832836

833-
adjusted_mu_i += margin_adjustment / comparison_count
837+
adjusted_mu_i += (
838+
(margin_adjustment / comparison_count)
839+
if comparison_count
840+
else margin_adjustment
841+
)
834842

835843
i_mu_over_c = math.exp(adjusted_mu_i / c)
836844

@@ -1075,10 +1083,8 @@ def _calculate_team_ratings(
10751083
10761084
:return: A list of :class:`PlackettLuceTeamRating` objects.
10771085
"""
1078-
if ranks:
1079-
rank = self._calculate_rankings(game, ranks)
1080-
else:
1081-
rank = self._calculate_rankings(game)
1086+
if ranks is None:
1087+
ranks = self._calculate_rankings(game)
10821088

10831089
result = []
10841090
for index, team in enumerate(game):
@@ -1097,7 +1103,7 @@ def _calculate_team_ratings(
10971103
sigma_squared_summed += (player.sigma * balance_weight) ** 2
10981104
result.append(
10991105
PlackettLuceTeamRating(
1100-
mu_summed, sigma_squared_summed, team, int(rank[index])
1106+
mu_summed, sigma_squared_summed, team, int(ranks[index])
11011107
)
11021108
)
11031109
return result
@@ -1124,15 +1130,15 @@ def _calculate_rankings(
11241130
return []
11251131

11261132
if ranks:
1127-
team_scores = [ranks[i] or i for i, _ in enumerate(game)]
1133+
team_scores = []
1134+
for index, _ in enumerate(game):
1135+
team_scores.append(ranks[index] or index)
11281136
else:
11291137
team_scores = [i for i, _ in enumerate(game)]
11301138

1131-
output_ranks: dict[int, float] = {}
1132-
s = 0
1133-
for index, value in enumerate(team_scores):
1134-
if index > 0:
1135-
if team_scores[index - 1] < team_scores[index]:
1136-
s = index
1137-
output_ranks[index] = s
1138-
return list(output_ranks.values())
1139+
sorted_scores = sorted(team_scores)
1140+
rank_map: dict[float, int] = {}
1141+
for index, value in enumerate(sorted_scores):
1142+
if value not in rank_map:
1143+
rank_map[value] = index
1144+
return [rank_map[v] for v in team_scores]

openskill/models/weng_lin/thurstone_mosteller_full.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,15 +1117,15 @@ def _calculate_rankings(
11171117
return []
11181118

11191119
if ranks:
1120-
team_scores = [ranks[i] or i for i, _ in enumerate(game)]
1120+
team_scores = []
1121+
for index, _ in enumerate(game):
1122+
team_scores.append(ranks[index] or index)
11211123
else:
11221124
team_scores = [i for i, _ in enumerate(game)]
11231125

1124-
output_ranks: dict[int, float] = {}
1125-
s = 0
1126-
for index, value in enumerate(team_scores):
1127-
if index > 0:
1128-
if team_scores[index - 1] < team_scores[index]:
1129-
s = index
1130-
output_ranks[index] = s
1131-
return list(output_ranks.values())
1126+
sorted_scores = sorted(team_scores)
1127+
rank_map: dict[float, int] = {}
1128+
for index, value in enumerate(sorted_scores):
1129+
if value not in rank_map:
1130+
rank_map[value] = index
1131+
return [rank_map[v] for v in team_scores]

openskill/models/weng_lin/thurstone_mosteller_part.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,15 +1108,15 @@ def _calculate_rankings(
11081108
return []
11091109

11101110
if ranks:
1111-
team_scores = [ranks[i] or i for i, _ in enumerate(game)]
1111+
team_scores = []
1112+
for index, _ in enumerate(game):
1113+
team_scores.append(ranks[index] or index)
11121114
else:
11131115
team_scores = [i for i, _ in enumerate(game)]
11141116

1115-
output_ranks: dict[int, float] = {}
1116-
s = 0
1117-
for index, value in enumerate(team_scores):
1118-
if index > 0:
1119-
if team_scores[index - 1] < team_scores[index]:
1120-
s = index
1121-
output_ranks[index] = s
1122-
return list(output_ranks.values())
1117+
sorted_scores = sorted(team_scores)
1118+
rank_map: dict[float, int] = {}
1119+
for index, value in enumerate(sorted_scores):
1120+
if value not in rank_map:
1121+
rank_map[value] = index
1122+
return [rank_map[v] for v in team_scores]

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ description = "Multiplayer Rating System. No Friction."
5353
readme = "README.md"
5454
requires-python = "~=3.10"
5555
keywords = ["ranking", "trueskill", "statistics", "rating", "math", "rank"]
56-
license = {"text" = "MIT"}
56+
license = "MIT"
5757
classifiers = [
5858
"Development Status :: 5 - Production/Stable",
5959
"Intended Audience :: Developers",

0 commit comments

Comments
 (0)