Skip to content

Commit

Permalink
add perf_ceiling in rating computation
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaowuc1 committed Feb 28, 2025
1 parent 4d1b682 commit df74a5c
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions judge/ratings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from bisect import bisect
from math import pi, sqrt, tanh
from math import inf, pi, sqrt, tanh
from operator import attrgetter, itemgetter

from django.db import transaction
Expand All @@ -19,6 +19,7 @@
VAR_LIM = (sqrt(VAR_PER_CONTEST**2 + 4 * BETA2 * VAR_PER_CONTEST) - VAR_PER_CONTEST) / 2
SD_LIM = sqrt(VAR_LIM)
TANH_C = sqrt(3) / pi
PERF_CEILING_INCREMENT = 400


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


def recalculate_ratings(ranking, old_mean, times_ranked, historical_p):
def recalculate_ratings(ranking, old_mean, times_ranked, historical_p, perf_ceiling):
n = len(ranking)
new_p = [0.] * n
new_mean = [0.] * n

updated_bounds = [VALID_RANGE[0], min(VALID_RANGE[1], perf_ceiling)]

# Note: pre-multiply delta by TANH_C to improve efficiency.
delta = [TANH_C * sqrt(get_var(t) + VAR_PER_CONTEST + BETA2) for t in times_ranked]
p_tanh_terms = [(m, d, 1) for m, d in zip(old_mean, delta)]

# Calculate performance at index i.
def solve_idx(i, bounds=VALID_RANGE):
def solve_idx(i, bounds):
r = ranking[i]
y_tg = 0
for d, s in zip(delta, ranking):
Expand All @@ -111,8 +114,8 @@ def divconq(i, j):
new_mean = list(old_mean)
else:
# Calculate performance.
solve_idx(0)
solve_idx(n - 1)
solve_idx(0, updated_bounds)
solve_idx(n - 1, updated_bounds)
divconq(0, n - 1)

# Calculate mean.
Expand Down Expand Up @@ -160,6 +163,9 @@ def rate_contest(contest):
users = users.exclude(last_rating__lt=contest.rating_floor)
if contest.rating_ceiling is not None:
users = users.exclude(last_rating__gt=contest.rating_ceiling)
perf_ceiling = contest.rating_ceiling + PERF_CEILING_INCREMENT
else:
perf_ceiling = inf

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

rating, mean, performance = recalculate_ratings(ranking, old_mean, times_ranked, historical_p)
rating, mean, performance = recalculate_ratings(ranking, old_mean, times_ranked, historical_p, perf_ceiling)

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

0 comments on commit df74a5c

Please sign in to comment.