Elo评分算法是广泛使用的评分算法,用于对许多竞技游戏中的玩家进行排名。
ELO评分较高的玩家比ELO评分较低的玩家赢得游戏的可能性更高。每场比赛之后,球员的ELO评分都会更新。如果ELO评分较高的玩家获胜,则评分较低的玩家只能获得几分。但是,如果评分较低的玩家获胜,则评分较高的玩家的转移积分会更大。
Approach:
P1: Probability of winning of player with rating2
P2: Probability of winning of player with rating1.
P1 = (1.0 / (1.0 + pow(10, ((rating1 – rating2) / 400))));
P2 = (1.0 / (1.0 + pow(10, ((rating2 – rating1) / 400))));
Obviously, P1 + P2 = 1.
The rating of player is updated using the formula given below :-
rating1 = rating1 + K*(Actual Score – Expected score);
In most of the games, “Actual Score” is either 0 or 1 means player either wins or loose. K is a constant. If K is of a lower value, then the rating is changed by a small fraction but if K is of a higher value, then the changes in the rating are significant. Different organizations set a different value of K.
例子:
Suppose there is a live match on chess.com between two players
rating1 = 1200, rating2 = 1000;
P1 = (1.0 / (1.0 + pow(10, ((1000-1200) / 400)))) = 0.76
P2 = (1.0 / (1.0 + pow(10, ((1200-1000) / 400)))) = 0.24
And Assume constant K=30;
CASE-1 : Suppose Player 1 wins:
rating1 = rating1 + k*(actual – expected) = 1200+30(1 – 0.76) = 1207.2;
rating2 = rating2 + k*(actual – expected) = 1000+30(0 – 0.24) = 992.8;
Case-2 : Suppose Player 2 wins:
rating1 = rating1 + k*(actual – expected) = 1200+30(0 – 0.76) = 1177.2;
rating2 = rating2 + k*(actual – expected) = 1000+30(1 – 0.24) = 1022.8;
CPP
// CPP program for Elo Rating
#include
using namespace std;
// Function to calculate the Probability
float Probability(int rating1, int rating2)
{
return 1.0 * 1.0 / (1 + 1.0 *
pow(10, 1.0 * (rating1 - rating2) / 400));
}
// Function to calculate Elo rating
// K is a constant.
// d determines whether Player A wins or Player B.
void EloRating(float Ra, float Rb, int K, bool d)
{
// To calculate the Winning
// Probability of Player B
float Pb = Probability(Ra, Rb);
// To calculate the Winning
// Probability of Player A
float Pa = Probability(Rb, Ra);
// Case -1 When Player A wins
// Updating the Elo Ratings
if (d == 1) {
Ra = Ra + K * (1 - Pa);
Rb = Rb + K * (0 - Pb);
}
// Case -2 When Player B wins
// Updating the Elo Ratings
else {
Ra = Ra + K * (0 - Pa);
Rb = Rb + K * (1 - Pb);
}
cout << "Updated Ratings:-\n";
cout << "Ra = " << Ra << " Rb = " << Rb;
}
int main()
{
// Ra and Rb are current ELO ratings
float Ra = 1200, Rb = 1000;
int K = 30;
bool d = 1;
EloRating(Ra, Rb, K, d);
return 0;
}
Java
// Java program to count rotationally
// equivalent rectangles with n unit
// squares
class GFG {
// Function to calculate the Probability
static float Probability(float rating1,
float rating2)
{
return 1.0f * 1.0f / (1 + 1.0f *
(float)(Math.pow(10, 1.0f *
(rating1 - rating2) / 400)));
}
// Function to calculate Elo rating
// K is a constant.
// d determines whether Player A wins
// or Player B.
static void EloRating(float Ra, float Rb,
int K, boolean d)
{
// To calculate the Winning
// Probability of Player B
float Pb = Probability(Ra, Rb);
// To calculate the Winning
// Probability of Player A
float Pa = Probability(Rb, Ra);
// Case -1 When Player A wins
// Updating the Elo Ratings
if (d == true) {
Ra = Ra + K * (1 - Pa);
Rb = Rb + K * (0 - Pb);
}
// Case -2 When Player B wins
// Updating the Elo Ratings
else {
Ra = Ra + K * (0 - Pa);
Rb = Rb + K * (1 - Pb);
}
System.out.print("Updated Ratings:-\n");
System.out.print("Ra = " + (Math.round(
Ra * 1000000.0) / 1000000.0)
+ " Rb = " + Math.round(Rb
* 1000000.0) / 1000000.0);
}
//driver code
public static void main (String[] args)
{
// Ra and Rb are current ELO ratings
float Ra = 1200, Rb = 1000;
int K = 30;
boolean d = true;
EloRating(Ra, Rb, K, d);
}
}
// This code is contributed by Anant Agarwal.
Python3
# Python 3 program for Elo Rating
import math
# Function to calculate the Probability
def Probability(rating1, rating2):
return 1.0 * 1.0 / (1 + 1.0 * math.pow(10, 1.0 * (rating1 - rating2) / 400))
# Function to calculate Elo rating
# K is a constant.
# d determines whether
# Player A wins or Player B.
def EloRating(Ra, Rb, K, d):
# To calculate the Winning
# Probability of Player B
Pb = Probability(Ra, Rb)
# To calculate the Winning
# Probability of Player A
Pa = Probability(Rb, Ra)
# Case -1 When Player A wins
# Updating the Elo Ratings
if (d == 1) :
Ra = Ra + K * (1 - Pa)
Rb = Rb + K * (0 - Pb)
# Case -2 When Player B wins
# Updating the Elo Ratings
else :
Ra = Ra + K * (0 - Pa)
Rb = Rb + K * (1 - Pb)
print("Updated Ratings:-")
print("Ra =", round(Ra, 6)," Rb =", round(Rb, 6))
# Driver code
# Ra and Rb are current ELO ratings
Ra = 1200
Rb = 1000
K = 30
d = 1
EloRating(Ra, Rb, K, d)
# This code is contributed by
# Smitha Dinesh Semwal
C#
// C# program to count rotationally equivalent
// rectangles with n unit squares
using System;
class GFG {
// Function to calculate the Probability
static float Probability(float rating1,
float rating2)
{
return 1.0f * 1.0f / (1 + 1.0f *
(float)(Math.Pow(10, 1.0f *
(rating1 - rating2) / 400)));
}
// Function to calculate Elo rating
// K is a constant.
// d determines whether Player A wins or
// Player B.
static void EloRating(float Ra, float Rb,
int K, bool d)
{
// To calculate the Winning
// Probability of Player B
float Pb = Probability(Ra, Rb);
// To calculate the Winning
// Probability of Player A
float Pa = Probability(Rb, Ra);
// Case -1 When Player A wins
// Updating the Elo Ratings
if (d == true) {
Ra = Ra + K * (1 - Pa);
Rb = Rb + K * (0 - Pb);
}
// Case -2 When Player B wins
// Updating the Elo Ratings
else {
Ra = Ra + K * (0 - Pa);
Rb = Rb + K * (1 - Pb);
}
Console.Write("Updated Ratings:-\n");
Console.Write("Ra = " + (Math.Round(Ra
* 1000000.0) / 1000000.0)
+ " Rb = " + Math.Round(Rb
* 1000000.0) / 1000000.0);
}
//driver code
public static void Main()
{
// Ra and Rb are current ELO ratings
float Ra = 1200, Rb = 1000;
int K = 30;
bool d = true;
EloRating(Ra, Rb, K, d);
}
}
// This code is contributed by Anant Agarwal.
输出:
Updated Ratings:-
Ra = 1207.207642 Rb = 992.792419
时间复杂度
算法的时间复杂度主要取决于pow函数的复杂度,其pow函数
复杂度取决于计算机体系结构。
在x86上,这是恒定时间操作:-O(1)
参考
http://www.gautamnarula.com/rating/