如何修改Elo评级以获得更高的分数?

时间:2013-06-12 21:27:39

标签: javascript algorithm rating-system

问题:

如果你从底部http://www.newedenfaces.com/向下看,你可以看到玩家排行榜。每个人都开始时的基本分数 1400 。目前,数据库中有超过1100名玩家,每次投票时都会随机挑选两名玩家。截至目前,最高评级 1572 。此外排行榜非常不稳定今天进入前十名的人现在处于70+范围内

我希望得分更重要。排行榜中的大多数人只是少数评级,有些甚至评级。

对于丑陋和冗长的代码感到抱歉。我稍后需要重构它。

eloRating: function(winnerIndex) {

    var kFactor = 16;

    if (winnerIndex == 0) {
      // A won
      var ratingA = this.collection.at(0).get('rating');
      var ratingB = this.collection.at(1).get('rating');

      var scoreA = this.collection.at(0).get('wins');
      var scoreB = this.collection.at(1).get('wins');

      var expectedA = 1.0 / (1.0 + Math.pow(10, ((ratingA - ratingB) / 400)));
      var expectedB = 1.0 / (1.0 + Math.pow(10, ((ratingA - ratingB) / 400)));

      var newRatingA = ratingA + (kFactor * expectedA);
      var newRatingB = ratingB - (kFactor * expectedA);

      this.collection.at(0).set('rating', Math.round(newRatingA));
      this.collection.at(1).set('rating', Math.round(newRatingB));
    } else {
      // B won
      var ratingA = this.collection.at(0).get('rating');
      var ratingB = this.collection.at(1).get('rating');

      var scoreA = this.collection.at(0).get('wins');
      var scoreB = this.collection.at(1).get('wins');

      var expectedA = 1.0 / (1.0 + Math.pow(10, ((ratingB - ratingA) / 400)));
      var expectedB = 1.0 / (1.0 + Math.pow(10, ((ratingB - ratingA) / 400)));

      var newRatingA = ratingA - (kFactor * expectedA);
      var newRatingB = ratingB + (kFactor * expectedA);

      this.collection.at(0).set('rating', Math.round(newRatingA));
      this.collection.at(1).set('rating', Math.round(newRatingB));
    }

2 个答案:

答案 0 :(得分:1)

您对预期分数的等式不正确。例如,根据你的等式,某人高出400分,预期得分为10/11(0.909)。这是不对的,因为实际获胜概率高于此(约0.919)。这是真正的等式:

ELO win probability

其中D是标准偏差中的点数(通常为400点)。该等式没有封闭形式,因此必须使用预先计算的值表。

另外,更重要的是,您没有正确计算调整。获胜者获得(1- e )** k *分。失败者失去( e )** k *点,其中 e 是玩家的预期得分。因此,如果玩家A比B高出400点并获胜,那么他获得(1-0.919)* k = 1.296点,失败者损失1.296点。在你的计算中,获胜者获得14.7分(!!!),失败者输掉14.7分。

答案 1 :(得分:1)

这是我的第一篇文章,但我想出了这个,这似乎是一种相当简洁的方法。

我希望它可以帮助某人。

var aElo = 1400; // player
var bElo = 1400; // opponent
var Res  = 1     // Result... 0.5 = draw, 1 = win, 0 = loss

var nElo = aElo+Math.round((32-((Math.floor(aElo/2101)+Math.floor(aElo/2401))*8)) * (Res - (1 / (1 + Math.pow(10, -(aElo - bElo) / 400)))));

alert("Players Elo was "+aElo+" but is now "+nElo);