《社交網絡》裏的Mark Zackburg被女友甩後,在舍友的啓發下,充分發揮了技術宅男自娛自樂的惡搞天分,作出了Facemash網站,對學校女生的相貌進行排名打分,結果網站訪問流量過大,直接把學校網絡搞癱瘓了。Facemask大受歡迎的關鍵就在於Zackburg基友Eduardo寫在窗戶上的排名公式,看電影之時就對這個排名公式很是感興趣,上網瞭解下,才發現這條公式就是大名鼎鼎的ELO等級分制度。ELO的應用很是普遍,大部分棋類比賽,如今流行的Moba遊戲,像11平臺的DOTA天梯系統,都是採用ELO等級分。算法
之後作競技類的遊戲排行榜能夠用ELO來排名,更真實地反映玩家的實力。閒來無事,作了個flash的Facemask,挺有意思的。網絡
ELO的實現代碼app
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建立的一個衡量各種對弈活動水平的評價方法,是當今對弈水平評估的公認的權威方法。被普遍用於國際象棋、圍棋、足球、籃球等運動。網絡遊戲英雄聯盟、魔獸世界內的競技對戰系統也採用此分級制度。this
ELO等級分制度是基於統計學的一個評估棋手水平的方法。美國國際象棋協會在1960年首先使用這種計分方法。因爲它比先前的方法更公平客觀,這種方法很快流行開來。1970年國際棋聯正式開始使用等級分制度。spa
Elo模型原先採用正態分佈。可是實踐顯明棋手的表現並不是呈正態分佈,因此如今的等級分計分系統一般使用的是Logistic distribution。code
假設棋手A和B的當前等級分分別爲和
,則按Logistic distribution A對B的勝率指望值當爲htm
相似B對A的勝率爲blog
假如一位棋手在比賽中的真實得分(勝=1分,和=0.5分,負=0分)和他的勝率指望值
不一樣,則他的等級分要做相應的調整。具體的數學公式爲遊戲
公式中和
分別爲棋手調整先後的等級分。在大師級比賽中
一般爲16。
例如,棋手A等級分爲1613,與等級分爲1573的棋手B戰平。若K取32,則A的勝率指望值爲,約爲0.5573,於是A的新等級分爲1613 + 32 · (0.5 − 0.5573) = 1611.166
國際象棋中,等級分和棋聯稱號的大體對應爲
其餘參考: