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 players 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:
#include <bits/stdc++.h>
using namespace std;
// Function to calculate the Probability
float Probability(int rating1, int rating2)
{
// Calculate and return the expected score
return 1.0 / (1 + pow(10, (rating1 - rating2) / 400.0));
}
// Function to calculate Elo rating
// K is a constant.
// outcome determines the outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw.
void EloRating(float Ra, float Rb, int K, float outcome)
{
// Calculate the Winning Probability of Player B
float Pb = Probability(Ra, Rb);
// Calculate the Winning Probability of Player A
float Pa = Probability(Rb, Ra);
// Update the Elo Ratings
Ra = Ra + K * (outcome - Pa);
Rb = Rb + K * ((1 - outcome) - Pb);
// Print updated ratings
cout << "Updated Ratings:-\n";
cout << "Ra = " << Ra << " Rb = " << Rb << endl;
}
// Driver code
int main()
{
// Current ELO ratings
float Ra = 1200, Rb = 1000;
// K is a constant
int K = 30;
// Outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw
float outcome = 1;
// Function call
EloRating(Ra, Rb, K, outcome);
return 0;
}
import java.lang.Math;
public class EloRating {
// Function to calculate the Probability
public static double Probability(int rating1, int rating2) {
// Calculate and return the expected score
return 1.0 / (1 + Math.pow(10, (rating1 - rating2) / 400.0));
}
// Function to calculate Elo rating
// K is a constant.
// outcome determines the outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw.
public static void EloRating(double Ra, double Rb, int K, double outcome) {
// Calculate the Winning Probability of Player B
double Pb = Probability(Ra, Rb);
// Calculate the Winning Probability of Player A
double Pa = Probability(Rb, Ra);
// Update the Elo Ratings
Ra = Ra + K * (outcome - Pa);
Rb = Rb + K * ((1 - outcome) - Pb);
// Print updated ratings
System.out.println("Updated Ratings:-");
System.out.println("Ra = " + Ra + " Rb = " + Rb);
}
public static void main(String[] args) {
// Current ELO ratings
double Ra = 1200, Rb = 1000;
// K is a constant
int K = 30;
// Outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw
double outcome = 1;
// Function call
EloRating(Ra, Rb, K, outcome);
}
}
import math
# Function to calculate the Probability
def probability(rating1, rating2):
# Calculate and return the expected score
return 1.0 / (1 + math.pow(10, (rating1 - rating2) / 400.0))
# Function to calculate Elo rating
# K is a constant.
# outcome determines the outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw.
def elo_rating(Ra, Rb, K, outcome):
# Calculate the Winning Probability of Player B
Pb = probability(Ra, Rb)
# Calculate the Winning Probability of Player A
Pa = probability(Rb, Ra)
# Update the Elo Ratings
Ra = Ra + K * (outcome - Pa)
Rb = Rb + K * ((1 - outcome) - Pb)
# Print updated ratings
print("Updated Ratings:-")
print(f"Ra = {Ra} Rb = {Rb}")
# Current ELO ratings
Ra = 1200
Rb = 1000
# K is a constant
K = 30
# Outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw
outcome = 1
# Function call
elo_rating(Ra, Rb, K, outcome)
using System;
class EloRating
{
// Function to calculate the Probability
public static double Probability(int rating1, int rating2)
{
// Calculate and return the expected score
return 1.0 / (1 + Math.Pow(10, (rating1 - rating2) / 400.0));
}
// Function to calculate Elo rating
// K is a constant.
// outcome determines the outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw.
public static void CalculateEloRating(ref double Ra, ref double Rb, int K, double outcome)
{
// Calculate the Winning Probability of Player B
double Pb = Probability((int)Ra, (int)Rb);
// Calculate the Winning Probability of Player A
double Pa = Probability((int)Rb, (int)Ra);
// Update the Elo Ratings
Ra = Ra + K * (outcome - Pa);
Rb = Rb + K * ((1 - outcome) - Pb);
}
static void Main()
{
// Current ELO ratings
double Ra = 1200, Rb = 1000;
// K is a constant
int K = 30;
// Outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw
double outcome = 1;
// Function call
CalculateEloRating(ref Ra, ref Rb, K, outcome);
// Print updated ratings
Console.WriteLine("Updated Ratings:-");
Console.WriteLine($"Ra = {Ra} Rb = {Rb}");
}
}
// Function to calculate the Probability
function probability(rating1, rating2) {
// Calculate and return the expected score
return 1 / (1 + Math.pow(10, (rating1 - rating2) / 400));
}
// Function to calculate Elo rating
// K is a constant.
// outcome determines the outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw.
function eloRating(Ra, Rb, K, outcome) {
// Calculate the Winning Probability of Player B
let Pb = probability(Ra, Rb);
// Calculate the Winning Probability of Player A
let Pa = probability(Rb, Ra);
// Update the Elo Ratings
Ra = Ra + K * (outcome - Pa);
Rb = Rb + K * ((1 - outcome) - Pb);
// Print updated ratings
console.log("Updated Ratings:-");
console.log(`Ra = ${Ra} Rb = ${Rb}`);
}
// Current ELO ratings
let Ra = 1200, Rb = 1000;
// K is a constant
let K = 30;
// Outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw
let outcome = 1;
// Function call
eloRating(Ra, Rb, K, outcome);
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)