【发布时间】:2010-11-08 01:58:52
【问题描述】:
短版:
我有一个与 StackOverflow 类似的设置。用户获得成就。我的成就比 SO 多得多,可以说大约 10k,每个用户都有 100 多个成就。现在,您将如何推荐(推荐)用户尝试的下一个成就?
长版:
这些对象在 django 中是这样建模的(仅显示重要部分):
class User(models.Model):
alias = models.ForeignKey(Alias)
class Alias(models.Model):
achievements = models.ManyToManyField('Achievement', through='Achiever')
class Achievement(models.Model):
points = models.IntegerField()
class Achiever(models.Model):
achievement = models.ForeignKey(Achievement)
alias = models.ForeignKey(Alias)
count = models.IntegerField(default=1)
我的算法只是找到与登录用户共享成就的所有其他用户,然后查看他们的所有成就并按出现次数排序:
def recommended(request) :
user = request.user.get_profile()
// The final response
r = {}
// Get all the achievements the user's aliases have received
// in a set so they aren't double counted
achievements = set()
for alias in user.alias_set.select_related('achievements').all() :
achievements.update(alias.achievements.all())
// Find all other aliases that have gotten at least one of the same
// same achievements as the user
otherAliases = set()
for ach in achievements :
otherAliases.update(ach.alias_set.all())
// Find other achievements the other users have gotten in addition to
// the shared ones.
// And count the number of times each achievement appears
for otherAlias in otherAliases :
for otherAch in otherAlias.achievements.all() :
r[otherAch] = r.get(otherAch, 0) + 1
// Remove all the achievements that the user has already gotten
for ach in achievements :
r.pop(ach)
// Sort by number of times the achievements have been received
r = sorted(r.items(), lambda x, y: cmp(x[1], y[1]), reverse=True)
// Put in the template for showing on the screen
template_values = {}
template_values['achievements'] = r
但它需要 FOREVER 才能运行,并且总是返回整个列表,这是不需要的。用户只需要前几项成就即可。
所以,欢迎我就其他算法和/或代码改进提出建议。我会在我的系统中为您提供推荐算法的成就:)
【问题讨论】:
-
您能否在代码中添加一些 cmets 来解释每个 for 循环的作用?抱歉对 django 不太熟悉,所以无法判断您的算法是什么。
-
我不明白您如何编码每个成就的条件以及用户已经满足的条件,这肯定与您的目标相关-您能解释一下吗?
-
当然。添加 cmets。感谢您的帮助
标签: python django optimization achievements