Add related problems

This commit is contained in:
cuom1999 2023-01-27 19:15:37 -06:00
parent 03455fca2c
commit ca13ee4e8d
7 changed files with 116 additions and 84 deletions

View file

@ -65,7 +65,7 @@ class CollabFilter:
return res
# return a list of pid
def problems_neighbors(self, problem, problemset, measure=DOT, limit=None):
def problem_neighbors(self, problem, problemset, measure=DOT, limit=None):
pid = problem.id
if pid >= len(self.problem_embeddings):
return None
@ -74,7 +74,7 @@ class CollabFilter:
)
res = []
for p in problemset:
if p.id < len(scores):
res.append((scores[p.id], p))
if p < len(scores):
res.append((scores[p], p))
res.sort(reverse=True, key=lambda x: x[0])
return res[:limit]

View file

@ -1,6 +1,8 @@
from collections import defaultdict
from math import e
import os, zipfile
from datetime import datetime
import random
from django.conf import settings
from django.core.cache import cache
@ -10,6 +12,8 @@ from django.utils import timezone
from django.utils.translation import gettext as _, gettext_noop
from judge.models import Problem, Submission
from judge.ml.collab_filter import CollabFilter
__all__ = [
"contest_completed_ids",
@ -229,3 +233,20 @@ def hot_problems(duration, limit):
cache.set(cache_key, qs, 900)
return qs
def get_related_problems(profile, problem, limit=8):
if not profile:
return None
problemset = Problem.get_visible_problems(profile.user).values_list("id", flat=True)
problemset = problemset.exclude(id__in=user_completed_ids(profile))
problemset = problemset.exclude(id=problem.id)
cf_model = CollabFilter("collab_filter")
results = cf_model.problem_neighbors(
problem, problemset, CollabFilter.DOT, limit
) + cf_model.problem_neighbors(problem, problemset, CollabFilter.COSINE, limit)
results = list(set([i[1] for i in results]))
seed = datetime.now().strftime("%d%m%Y")
random.Random(seed).shuffle(results)
results = results[:limit]
return [Problem.objects.get(id=i) for i in results]

View file

@ -76,6 +76,7 @@ from judge.utils.problems import (
hot_problems,
user_attempted_ids,
user_completed_ids,
get_related_problems,
)
from judge.utils.strings import safe_float_or_none, safe_int_or_none
from judge.utils.tickets import own_ticket_filter
@ -352,6 +353,10 @@ class ProblemDetail(
else:
context["fileio_input"] = None
context["fileio_output"] = None
if not self.in_contest:
context["related_problems"] = get_related_problems(
self.profile, self.object
)
return context