Elo Rating Algorithm
Last Updated :
25 Jan, 2023
The Elo Rating Algorithm is a widely used rating algorithm used to rank players in many competitive games.
Players with higher ELO ratings have a higher probability of winning a game than a player with lower ELO ratings. After each game, the ELO rating of players is updated. If a player with a higher ELO rating wins, only a few points are transferred from the lower-rated player. However if the lower-rated player wins, then the transferred points from a higher-rated player are far greater.
Approach: To Solve the problem follow the below idea:
P1: Probability of winning of the player with rating2, P2: Probability of winning of the 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 the 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 the 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.
Example:
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;
Follow the below steps to solve the problem:
- Calculate the probability of winning of players A and B using the formula given above
- If player A wins or player B wins then the ratings are updated accordingly using the formulas:
- rating1 = rating1 + K*(Actual Score – Expected score)
- rating2 = rating2 + K*(Actual Score – Expected score)
- Where the Actual score is 0 or 1
- Print the updated ratings
Below is the implementation of the above approach:
CPP
#include <bits/stdc++.h>
using namespace std;
float Probability( int rating1, int rating2)
{
return 1.0 * 1.0
/ (1
+ 1.0
* pow (10,
1.0 * (rating1 - rating2) / 400));
}
void EloRating( float Ra, float Rb, int K, bool d)
{
float Pb = Probability(Ra, Rb);
float Pa = Probability(Rb, Ra);
if (d == 1) {
Ra = Ra + K * (1 - Pa);
Rb = Rb + K * (0 - Pb);
}
else {
Ra = Ra + K * (0 - Pa);
Rb = Rb + K * (1 - Pb);
}
cout << "Updated Ratings:-\n" ;
cout << "Ra = " << Ra << " Rb = " << Rb;
}
int main()
{
float Ra = 1200, Rb = 1000;
int K = 30;
bool d = 1;
EloRating(Ra, Rb, K, d);
return 0;
}
|
Java
class GFG {
static float Probability( float rating1, float rating2)
{
return 1 .0f * 1 .0f
/ ( 1
+ 1 .0f
* ( float )(Math.pow(
10 , 1 .0f * (rating1 - rating2)
/ 400 )));
}
static void EloRating( float Ra, float Rb, int K,
boolean d)
{
float Pb = Probability(Ra, Rb);
float Pa = Probability(Rb, Ra);
if (d == true ) {
Ra = Ra + K * ( 1 - Pa);
Rb = Rb + K * ( 0 - Pb);
}
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 );
}
public static void main(String[] args)
{
float Ra = 1200 , Rb = 1000 ;
int K = 30 ;
boolean d = true ;
EloRating(Ra, Rb, K, d);
}
}
|
Python3
import math
def Probability(rating1, rating2):
return 1.0 * 1.0 / ( 1 + 1.0 * math. pow ( 10 , 1.0 * (rating1 - rating2) / 400 ))
def EloRating(Ra, Rb, K, d):
Pb = Probability(Ra, Rb)
Pa = Probability(Rb, Ra)
if (d = = 1 ):
Ra = Ra + K * ( 1 - Pa)
Rb = Rb + K * ( 0 - Pb)
else :
Ra = Ra + K * ( 0 - Pa)
Rb = Rb + K * ( 1 - Pb)
print ( "Updated Ratings:-" )
print ( "Ra =" , round (Ra, 6 ), " Rb =" , round (Rb, 6 ))
Ra = 1200
Rb = 1000
K = 30
d = 1
EloRating(Ra, Rb, K, d)
|
C#
using System;
class GFG {
static float Probability( float rating1, float rating2)
{
return 1.0f * 1.0f
/ (1
+ 1.0f
* ( float )(Math.Pow(
10, 1.0f * (rating1 - rating2)
/ 400)));
}
static void EloRating( float Ra, float Rb, int K, bool d)
{
float Pb = Probability(Ra, Rb);
float Pa = Probability(Rb, Ra);
if (d == true ) {
Ra = Ra + K * (1 - Pa);
Rb = Rb + K * (0 - Pb);
}
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);
}
public static void Main()
{
float Ra = 1200, Rb = 1000;
int K = 30;
bool d = true ;
EloRating(Ra, Rb, K, d);
}
}
|
JavaScript
function Probability(rating1, rating2) {
return (
(1.0 * 1.0) / (1 + 1.0 * Math.pow(10, (1.0 * (rating1 - rating2)) / 400))
);
}
function EloRating(Ra, Rb, K, d) {
let Pb = Probability(Ra, Rb);
let Pa = Probability(Rb, Ra);
if (d === true ) {
Ra = Ra + K * (1 - Pa);
Rb = Rb + K * (0 - Pb);
}
else {
Ra = Ra + K * (0 - Pa);
Rb = Rb + K * (1 - Pb);
}
console.log( "Updated Ratings:-" );
console.log(
"Ra = " +
Math.round(Ra * 1000000.0) / 1000000.0 +
" Rb = " +
Math.round(Rb * 1000000.0) / 1000000.0
);
}
const Ra = 1200;
const Rb = 1000;
const K = 30;
const d = true ;
EloRating(Ra, Rb, K, d);
</script>
|
Output
Updated Ratings:-
Ra = 1207.21 Rb = 992.792
Time Complexity: The time complexity of the algorithm depends mostly on the complexity of the pow function whose complexity is dependent on Computer Architecture. On x86, this is constant time operation:-O(1)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...