基于用户投票的排名算法的PHP实现之 Reddit 篇

本文算法参考: 基于用户投票的排名算法(二):Reddit 实现

Reddit是美国最大的网上社区,它的每个帖子前面都有向上和向下的箭头,分别表示”赞成”和”反对”。用户点击进行投票,Reddit根据投票结果,计算出最新的”热点文章排行榜”。
该社区的算法特点是最受欢迎(支持远超反对)的post排在前段, 正反观点相近的post排中间, 大量反对的post排后面.同时参考了时效性, PHP代码如下:

<?php
//获得赞成票
$vote = 100;
//获得的反对票
$devote = 99;
//投票差额
$voteDiff = $vote - $devote;
//投票方向
if($voteDiff > 0) {
    $pos = 1;
} elseif($voteDiff < 0) {
    $pos = -1;
} else {
    $pos = 0;
}
//帖子的争议度(赞成/否定)
$voteDispute = $voteDiff != 0 ? abs($voteDiff) : 1;

//项目创建时间
$fund = strtotime('2012-09-01');
//数据创建时间
$created = strtotime('-3 days');
//考虑时间因素, 用来拉低比较老的post的分数
$time = $created - $fund;
//详细算法
$socre = log10($voteDispute) + $pos * $time / 45000;
echo $socre, "\n";

注: log10($voteDispute) 计算的是以10为底的的对数, 争议程度会影响得分, 但是争议度很大的时候对整体得分的影响不是很明显,避免了一些争议很大的老的post会给新的post带来排名压力

4 评论

  1. 请教一下,您这个是计算单条记录的排名,如果我想使用您的算法计算数据库里所有记录的排名,该怎么做呢?

  2. 你好,不是很明白那个log10求对数的作用,和45000这个数的作用,据说是12.5小时,但不是很明白,请教大神,我昨天也发过邮件给你,不知能否抽空指教一下呢?谢谢。。

    1. 你可以搜一下log10 的函数图, 当log10的参数很大时, 曲线的偏差也不很大, 这样就可以有效避免老帖因为争议过大而, 影响了新帖的排名, 但是少量的争议应该也需要影响到帖子的排名.而45000是12.5小时,这样除法,会产生后一天的帖子会前一天的帖子多得2分两分的效果,从而在时间上实现对新帖子的排序加分.
      最后是, 你发的邮件我并没有收到不好意思.

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.