Я работаю на доске обсуждений, которая перечисляет все темы в зависимости от их популярности / популярности (например, Reddit). Поэтому я взял алгоритм Reddits и начал пытаться. я использовал этот пример: http://blog.sodhanalibrary.com/2014/04/reddit-ranking-algorithm-implementation.html
function score($ups,$downs){
return $ups - $downs;
}
function epoch_seconds($timestamp){
$epoch = new DateTime("1970-01-01 00:00:00");
$unix = new DateTime($timestamp);
$td = $epoch->diff($unix);
$days = $td->format('%a');
$hours = $td->format('%h');
$minutes = $td->format('%i');
$seconds = $td->format('%s');
$age = ($days * 86400) + ($hours * 3600) + ($minutes * 60) + $seconds;
return $age;
}
function calculateRank($ups,$downs,$date){
$s = score($ups,$downs);
$order = log10(max(abs($s), 1), 10);
if($s > 0) {
$sign = 1;
} elseif($s < 0) {
$sign = -1;
} else {
$sign = 0;
}
$seconds = epoch_seconds($date) - 1134028003;
return round($order + (($sign * $seconds)/45000), 7);
}
Пример:
echo calculateRank(1,0,"2015-02-14 12:00:00"); // = 6441.9377111
Что я не понимаю, так это тот факт, что если оценка (разница между положительными и отрицательными голосами) равна 0, тогда ранг равен 0. Это будет означать, что совершенно новая статья с + 1 / -1 будет оценена в нирвана.
echo calculateRank(1,1,"2015-02-14 12:00:00"); // = 0
Кроме того, если оценка отрицательная, ранг отрицательный. Это означает, что совершенно новая статья с + 1 / -2 будет оцениваться еще дальше, чем нирвана.
echo calculateRank(1,2,"2015-02-14 12:00:00"); // = -6441.9377111
Запрос выбора будет выглядеть примерно так:
SELECT * FROM articles ORDER BY rank DESC
Согласно результатам, которые я вам показал, это будет означать, что 10-летняя статья с положительным баллом (например, 1 upvote / 0 downvotes) будет иметь более высокий рейтинг, чем КАЖДАЯ статья с баллом 0 или отрицательным баллом, нет вопрос даты. Это не может быть правдой и смущает меня.
То, что я ищу, это нечто подобное. Я уже избавился от нулевых разрядов, не допустив, чтобы оценка была равна 0. Однако отрицательные оценки (например, 0 повышенных голосов / 2 понижающих голоса) должны понизить счет вместо того, чтобы инвертировать его.
Любая помощь высоко ценится!
Благодарю.
Я настроил алгоритм под свои нужды.
Я придумал следующее:
if($score >= 0) {
$sign = 1;
} elseif($score < 0) {
$sign = -1;
}
return round( ($sign * $order) + ($seconds / 45000) , 7);
Таким образом, статьи с отрицательным счетом будут просто понижать рейтинг, а не инвертировать его. (наказание за оценку -1, например, не должно быть: «иди в нирвану!»)
Других решений пока нет …