• 《社交网络》里的评分公式——ELO排名系统


      《社交网络》里的Mark Zackburg被女朋友甩后,在舍友的启发下,充分发挥了技术宅男自娱自乐的恶搞天分,做出了Facemash网站,对学校女生的相貌进行排名打分,结果网站访问流量过大,直接把学校网络搞瘫痪了。Facemask大受欢迎的关键就在于Zackburg基友Eduardo写在窗户上的排名公式,看电影之时就对这个排名公式非常感兴趣,上网了解下,才发现这条公式就是大名鼎鼎的ELO等级分制度ELO的应用非常广泛,大部分棋类比赛,现在流行的Moba游戏,像11平台的DOTA天梯系统,都是采用ELO等级分。

      以后做竞技类的游戏排行榜可以用ELO来排名,更真实地反映玩家的实力。闲来无事,做了个flash的Facemask,挺有意思的。

    ELO的实现代码

    package
    {
        
        /**
         * Elo排名算法
         * @author ShuchangLiu
         */
        public class EloRating
        {
            public static const ELO_RESULT_WIN:int = 1;
            public static const ELO_RESULT_LOSS:int = -1;
            public static const ELO_RESULT_TIE:int = 0;
            
            public static const ELO_RATING_DEFAULT:int = 1500;
            
            protected var rating1:int;
            protected var rating2:int;
            protected var score1:Number;
            protected var score2:Number;
            
            public function EloRating(rating1:int = ELO_RATING_DEFAULT, rating2:int = ELO_RATING_DEFAULT):void
            {
                this.rating1 = rating1;
                this.rating2 = rating2;
            }
            
            /**
             * @param result ELO_RESULT_WIN or ELO_RESULT_LOSS or ELO_RESULT_TIE
             */        
            public function setResult(result:int):void {
                var cscore1:Number = computeScore(this.rating2, this.rating1);
                var cscore2:Number = computeScore(this.rating1, this.rating2);
                
                if (result == ELO_RESULT_WIN) {
                    this.rating1 = this.rating1 + (computeK(this.rating1) * (1 - cscore1));
                    this.rating2 = this.rating2 + (computeK(this.rating2) * (0 - cscore2));
                }else if(result == ELO_RESULT_LOSS) {
                    this.rating1 = this.rating1 + (computeK(this.rating1) * (0 - cscore1));
                    this.rating2 = this.rating2 + (computeK(this.rating2) * (1 - cscore2));
                }else{
                    // Assume tie
                    this.rating1 = this.rating1 + (computeK(this.rating1) * (0.5 - cscore1));
                    this.rating2 = this.rating2 + (computeK(this.rating2) * (0.5 - cscore2));
                }
            }
            
            protected function computeScore($rating1:int, $rating2:int):Number {
                return (1 / (1 + Math.pow(10, ($rating1 - $rating2) / 400)));
            }
            
            protected function computeK(rating:int):int {
                if(rating>=2400){
                    return 16;
                }else if(rating >= 2100){
                    return 24;
                }else{
                    return 36;
                }
            }
            
            /** A的获胜期望*/
            public function getScore1():Number {
                this.score1 = computeScore(this.rating2, this.rating1);
                return this.score1;
            }
            
            /** B的获胜期望*/
            public function getScore2():Number {
                this.score2 = computeScore(this.rating1, this.rating2);
                return this.score2;
            }
            
            /** A的排名等级*/
            public function getRating1():int {
                return this.rating1;
            }
            
            /** B的排名等级*/
            public function getRating2():int {
                return this.rating2;
            }
            
            
            
        }
    }

    ELO介绍

    ELO等级分制度是指由匈牙利美国物理学家Elo创建的一个衡量各类对弈活动水平的评价方法,是当今对弈水平评估的公认的权威方法。被广泛用于国际象棋围棋足球篮球等运动。网络游戏英雄联盟魔兽世界内的竞技对战系统也采用此分级制度。

    历史

    ELO等级分制度是基于统计学的一个评估棋手水平的方法。美国国际象棋协会在1960年首先使用这种计分方法。由于它比先前的方法更公平客观,这种方法很快流行开来。1970年国际棋联正式开始使用等级分制度。

    Elo模型原先采用正态分布。但是实践显明棋手的表现并非呈正态分布,所以现在的等级分计分系统通常使用的是Logistic distribution

    计分方法

    假设棋手A和B的当前等级分分别为R_AR_B,则按Logistic distribution A对B的胜率期望值当为

    E_A = frac 1 {1 + 10^{(R_B - R_A)/400}}.

    类似B对A的胜率为

    E_B = frac 1 {1 + 10^{(R_A - R_B)/400}}.

    假如一位棋手在比赛中的真实得分S_A(胜=1分,和=0.5分,负=0分)和他的胜率期望值E_A不同,则他的等级分要作相应的调整。具体的数学公式为

    R_A^prime = R_A + K(S_A - E_A).

    公式中R_AR_A^prime分别为棋手调整前后的等级分。在大师级比赛中K通常为16。

    例如,棋手A等级分为1613,与等级分为1573的棋手B战平。若K取32,则A的胜率期望值为frac 1 {1 + 10^{(1573 - 1613)/400}},约为0.5573,因而A的新等级分为1613 + 32 · (0.5 − 0.5573) = 1611.166

    国际象棋中的等级分

    国际象棋中,等级分和棋联称号的大致对应为

    • 2500分以上:国际特级大师
    • 2400-2499分:国际大师
    • 2300-2399分:棋联大师 

    其他参考:

    ELO等级分计算公式详解

  • 相关阅读:
    1025 反转链表
    Vue--修饰符
    Vue--watch
    Vue--防止页面闪烁
    Vue--过滤器
    Vue--自定义指令
    Vue--生命周期
    vue--父子组件传递数据
    vue--父子组件调用彼此的方法
    Celery--beat
  • 原文地址:https://www.cnblogs.com/leoin2012/p/4854442.html
Copyright © 2020-2023  润新知