Dan*_*zie 5 php sorting algorithm math
我目前正在建立一个需要根据内部行动/得分排名的系统.分数本身可以在0到20000之间的任何范围内.
我需要我创建的功能来排名用户以返回1-100之间的值.如果这是不可能的,那么将100以上的结果集返回为100就可以了.我目前在确保创建用于确定分数的对数算法时遇到困难.
我试过以下功能:
echo 1 + sqrt(500 + 2000 * $score) / 50;
Run Code Online (Sandbox Code Playgroud)
但是,对于较低的值,此返回的结果不会变得足够大,而对于较高的值而言,该结果的指数增加.
在比例的低/平均结束时的示例输入分数是:
在秤的高端输入示例
任何帮助将不胜感激.现在已经坚持了几天.上面的函数是我迄今为止的最佳尝试,但是建议低/中结果之间没有足够的差异,而较高/结果之间的差异太大.
谢谢,
丹尼尔
这是一个开放式问题,并没有明确的答案,权衡不同。我不是 PHP 程序员,但类似以下内容应该可行。
# THESE PARAMETERS CONTROL THE RANKING ALGORITHM.
$rescale = 0;
$spread = 1;
function rescore ($n) {
return log($n) + $rescale;
}
function rank ($scores) {
return 100 / (1 + exp(- $spread * array_sum(array_map("rescore", $scores))));
}
Run Code Online (Sandbox Code Playgroud)
您应该选择$rescale使平均分数重新得分接近于 0。并不断尝试$spread直到您对分数的分布感到满意为止。
这个想法是log将广泛的分数转换为可比较范围内的数字,可以是正数也可以是负数。将一堆重新评分的分数加在一起,你会得到一个任意的实数。然后将其放入逻辑函数(有关详细信息,请参阅https://en.wikipedia.org/wiki/Logistic_function)以将其转换为所需范围内的数字。
谢谢您的帮助。这就是我最终得到的结果(感谢 Jake L Price 的帮助)
在最初的问题之后,分数略有不同(120,000 是最高分),但算法的逻辑需要保持不变。正如您在下面看到的,我们使用 log * 10 来获得一个可以理解的低数字。然后我们再次乘以一个数字,确保 120,000 的最高级别为 100。
echo $this->rank($score);
public function rank($score)
{
//-- log reg time
// 7.143963378055477 being the numberic multiplier to ensure 120,000 has the score of 100.
$res = 7.143963378055477 * log($score * 10);
return $res;
}
Run Code Online (Sandbox Code Playgroud)
现在正在返回
$scores = [0.15,1,7,12,236.4,1211,17899.70, 120000];
foreach ($scores as $score){
echo "Score: " . $score . ", Rank: " . $this->rank($score) . "</br>";
}
Run Code Online (Sandbox Code Playgroud)
输出:
Score: 0.15, Rank: 2.896627883404
Score: 1, Rank: 16.449583579206
Score: 7, Rank: 30.351094421044
Score: 12, Rank: 34.201665683178
Score: 236.4, Rank: 55.495096060882
Score: 1211, Rank: 67.166020848577
Score: 17899.7, Rank: 86.407125230156
Score: 120000, Rank: 100
Run Code Online (Sandbox Code Playgroud)