Skip to content

Commit df74a5c

Browse files
committed
add perf_ceiling in rating computation
1 parent 4d1b682 commit df74a5c

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

judge/ratings.py

+12-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from bisect import bisect
2-
from math import pi, sqrt, tanh
2+
from math import inf, pi, sqrt, tanh
33
from operator import attrgetter, itemgetter
44

55
from django.db import transaction
@@ -19,6 +19,7 @@
1919
VAR_LIM = (sqrt(VAR_PER_CONTEST**2 + 4 * BETA2 * VAR_PER_CONTEST) - VAR_PER_CONTEST) / 2
2020
SD_LIM = sqrt(VAR_LIM)
2121
TANH_C = sqrt(3) / pi
22+
PERF_CEILING_INCREMENT = 400
2223

2324

2425
def tie_ranker(iterable, key=attrgetter('points')):
@@ -77,17 +78,19 @@ def get_var(times_ranked, cache=[VAR_INIT]):
7778
return cache[times_ranked]
7879

7980

80-
def recalculate_ratings(ranking, old_mean, times_ranked, historical_p):
81+
def recalculate_ratings(ranking, old_mean, times_ranked, historical_p, perf_ceiling):
8182
n = len(ranking)
8283
new_p = [0.] * n
8384
new_mean = [0.] * n
8485

86+
updated_bounds = [VALID_RANGE[0], min(VALID_RANGE[1], perf_ceiling)]
87+
8588
# Note: pre-multiply delta by TANH_C to improve efficiency.
8689
delta = [TANH_C * sqrt(get_var(t) + VAR_PER_CONTEST + BETA2) for t in times_ranked]
8790
p_tanh_terms = [(m, d, 1) for m, d in zip(old_mean, delta)]
8891

8992
# Calculate performance at index i.
90-
def solve_idx(i, bounds=VALID_RANGE):
93+
def solve_idx(i, bounds):
9194
r = ranking[i]
9295
y_tg = 0
9396
for d, s in zip(delta, ranking):
@@ -111,8 +114,8 @@ def divconq(i, j):
111114
new_mean = list(old_mean)
112115
else:
113116
# Calculate performance.
114-
solve_idx(0)
115-
solve_idx(n - 1)
117+
solve_idx(0, updated_bounds)
118+
solve_idx(n - 1, updated_bounds)
116119
divconq(0, n - 1)
117120

118121
# Calculate mean.
@@ -160,6 +163,9 @@ def rate_contest(contest):
160163
users = users.exclude(last_rating__lt=contest.rating_floor)
161164
if contest.rating_ceiling is not None:
162165
users = users.exclude(last_rating__gt=contest.rating_ceiling)
166+
perf_ceiling = contest.rating_ceiling + PERF_CEILING_INCREMENT
167+
else:
168+
perf_ceiling = inf
163169

164170
users = list(users)
165171
participation_ids = list(map(itemgetter('id'), users))
@@ -176,7 +182,7 @@ def rate_contest(contest):
176182
idx = user_id_to_idx[h['user_id']]
177183
historical_p[idx].append(h['performance'])
178184

179-
rating, mean, performance = recalculate_ratings(ranking, old_mean, times_ranked, historical_p)
185+
rating, mean, performance = recalculate_ratings(ranking, old_mean, times_ranked, historical_p, perf_ceiling)
180186

181187
now = timezone.now()
182188
ratings = [Rating(user_id=i, contest=contest, rating=r, mean=m, performance=perf,

0 commit comments

Comments
 (0)