本章概述
从数学角度分析 分别用c java python演示算法机制
数学理论
预期胜率计算公式
积分算法
- elo使玩家尽量其股相当 双方实力进来保证持平
- elo算法基于预先假设:
- 一名选手的当前实力受各种因素的影响会在一定范围内波动,某个时刻的用来描述其实力的函数应当符合正态分布
- 两名选手进行对战时的预期胜率
分数迭代公式
- 以上积分公式只能看出来一个预期范围 如果想确定一名选手的准确"elo表现分"还需要总结出另外一个公式
参数 | 含义 |
Rn | 玩家比赛结束后的新的排位分值 |
Ro | 比赛前玩家的排位分 |
K | 一个加成系数,由玩家当前分值水平决定(分值越高K越小) |
W | 玩家实际对局结果得分(赢=1,输=0) |
P(D) | 预期胜率 |
Ra | A选手当前分数 |
Rb | B选手当前分数 |
Rn = Ro +K* (W - P(D))
- 预期A选手的胜负值
Ea = 1/(1+10^ [(Rb-Ra)/400])
- 预期B选手的胜负值
Eb = 1/(1+10^ [(Ra-Rb)/400])
c
#include <bits/stdc++.h> using namespace std; void updateRatingUsingELoRating(float rating1, float rating2, int ratingConstant, bool player1SuccessProb) { float P1, P2; if(rating1 > rating2){ P1 = (1.0 / (1.0 + pow(10.0, ((rating1 - rating2) / 400.0)) ) ); P2 = 1 - P1; } else { P2 = (1.0 / (1.0 + pow(10.0, ((rating2 - rating1) / 400.0)) ) ); P1 = 1 - P2; } if (player1SuccessProb == 1) { rating1 = rating1 + ratingConstant * (1 - P1); rating2 = rating2 + ratingConstant * (0 - P2); } else { rating1 = rating1 + ratingConstant * (0 - P1); rating1 = rating1 + ratingConstant * (1 - P2); } cout<<"Ratings After the game\n"; cout<<"Player 1 : "<<rating1<<"\t Player 2 : "<<rating2; } int main() { float rating1 = 782, rating2 = 1432; int ratingConstant = 100; bool player1SuccessProb = 1; cout<<"Ratings before the game: \n"; cout<<"Player 1 : "<<rating1<<"\t Player 2 : "<<rating2<<endl; if(player1SuccessProb) cout<<"Player 1 wins the game!\n"; else cout<<"Player 2 wins the game!\n"; updateRatingUsingELoRating(rating1, rating2, ratingConstant, player1SuccessProb); return 0; }
c++
使用Elo评级差异计算每个玩家获胜的概率。玩家A战胜玩家B的概率可以用公式来计算:P(A) = 1 / (1 + pow(10, (ratingB - ratingA) / 400))。同样,玩家B战胜玩家A的概率为:P(B) = 1 / (1 + pow(10, (ratingA - ratingB) / 400))。(来源:GeeksforGeeks)
确定游戏的实际结果。如果玩家A获胜,则实际得分为1。如果玩家B获胜,则实际得分为0。
根据实际结果和预期结果更新两名球员的评分。玩家A的新评分可以使用以下公式计算:newRatingA = ratingA + K * (actualScoreA - expectedScoreA),其中K是代表评分变化幅度的常数。玩家B的新评级也可以类似地计算出来。(来源:GeeksforGeeks)
Calculate the probabilities of winning for each player using the Elo rating difference. The probability of player A winning against player B can be calculated using the formula: P(A) = 1 / (1 + pow(10, (ratingB - ratingA) / 400)). Similarly, the probability of player B winning against player A is: P(B) = 1 / (1 + pow(10, (ratingA - ratingB) / 400)). (Source: GeeksforGeeks)
Determine the actual outcome of the game. If player A wins, the actual score is 1. If player B wins, the actual score is 0.
Update the ratings of both players based on the actual outcome and the expected outcome. The new rating for player A can be calculated using the formula: newRatingA = ratingA + K * (actualScoreA - expectedScoreA), where K is a constant representing the magnitude of rating changes. The new rating for player B can be calculated similarly. (Source: GeeksforGeeks)
#include <iostream> #include <cmath> // Function to calculate the probability of winning for player A float Probability(int ratingA, int ratingB) { return 1.0 / (1.0 + std::pow(10, (ratingB - ratingA) / 400.0)); } // Function to update Elo ratings based on the outcome of the game void EloRating(int& ratingA, int& ratingB, int K, int actualScoreA) { float expectedScoreA = Probability(ratingA, ratingB); float expectedScoreB = 1 - expectedScoreA; ratingA += K * (actualScoreA - expectedScoreA); ratingB += K * ((1 - actualScoreA) - expectedScoreB); } int main() { int ratingA = 1200; int ratingB = 1000; int K = 30; int actualScoreA = 1; EloRating(ratingA, ratingB, K, actualScoreA); std::cout << "Updated Ratings:\n"; std::cout << "Player A: " << ratingA << "\n"; std::cout << "Player B: " << ratingB << "\n"; return 0; }
#include <bits/stdc++.h> 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; } // Driver code int main() { // Ra and Rb are current ELO ratings float Ra = 1200, Rb = 1000; int K = 30; bool d = 1; // Function call EloRating(Ra, Rb, K, d); return 0; }
java
To implement the ELO algorithm for game matchmaking in Java
Define the ELO rating system: The ELO rating system is a widely used algorithm to rank players in competitive games. It assigns players a skill level based on their performance in matches. The ELO rating is updated after each match based on the outcome and the expected probability of winning. Calculate the expected probability of winning: Before a match, you need to calculate the expected probability of winning for each player. This can be done using the following formula:
P1 = 1 / (1 + Math.pow(10, (rating2 - rating1) / 400));
P2 = 1 / (1 + Math.pow(10, (rating1 - rating2) / 400));
Where rating1 and rating2 are the ELO ratings of the two players.
Update the ratings after the match: After the match is finished, you need to update the ELO ratings of the players based on the actual outcome and the expected probability of winning. The formula for updating the ratings is:
rating1 = rating1 + K * (actual - expected);
rating2 = rating2 + K * (actual - expected);
Where actual is the actual outcome of the match (0 for a loss, 1 for a win), expected is the expected probability of winning calculated in step 2, and K is a constant that determines the magnitude of rating changes.
public class EloMatchmaking { public static void main(String[] args) { int rating1 = 1200; int rating2 = 1000; int K = 30; double P1 = 1 / (1 + Math.pow(10, (rating2 - rating1) / 400)); double P2 = 1 / (1 + Math.pow(10, (rating1 - rating2) / 400)); // Suppose player 1 wins double actual = 1; double expected = P1; rating1 = (int) (rating1 + K * (actual - expected)); rating2 = (int) (rating2 + K * (actual - expected)); System.out.println("Updated ratings:"); System.out.println("Player 1: " + rating1); System.out.println("Player 2: " + rating2); } }
c#
public class EloRating { private const int K = 20; public static void UpdateEloRating(ref int rating1, ref int rating2, bool isFirstPlayerWin) { int delta = CalculateRatingChange(rating1, rating2, isFirstPlayerWin ? 1 : 0); rating1 += delta; rating2 -= delta; } private static int CalculateRatingChange(int rating1, int rating2, int actualScore) { double expectedScore = 1 / (1 + Math.Pow(10, (rating2 - rating1) / 400.0)); return (int) (K * (actualScore - expectedScore)); } }