Thuật toán Elo Rating dùng để xếp hạng người chơi trong các trò chơi đối kháng (cờ vua, game online...). Điểm rating thay đổi dựa trên kết quả trận đấu và xác suất thắng thua dự đoán.
Công thức cập nhật Rating
R_new = R_old + K * (S - E)
- R_old: Rating hiện tại.
- K: Hệ số điều chỉnh (K-factor), thường 10-40 (cờ vua) hoặc tùy game.
- S: Kết quả thực tế (Thắng=1, Hòa=0.5, Thua=0).
- E: Xác suất thắng dự đoán (Expected Score).
Xác suất thắng của Player A (Rating Ra) đối với Player B (Rating Rb):
Ea = 1 / (1 + 10^((Rb - Ra) / 400))
Eb = 1 - Ea
Ví dụ
Player 1: Ra=1200, Player 2: Rb=1000. K=30. Player 1 thắng.
Ea = 1 / (1 + 10^((1000-1200)/400)) = 1 / (1 + 10^(-0.5)) ≈ 0.76.
R1_new = 1200 + 30 * (1 - 0.76) = 1207.2
R2_new = 1000 + 30 * (0 - 0.24) = 992.8
Chương trình minh họa
#include <bits/stdc++.h>
using namespace std;
struct Player {
string name;
double rating;
};
double expectedScore(double ra, double rb) {
return 1.0 / (1.0 + pow(10.0, (rb - ra) / 400.0));
}
void updateElo(Player &p1, Player &p2, double kFactor, double score1) {
// score1: 1 (p1 thắng), 0.5 (hòa), 0 (p1 thua)
double e1 = expectedScore(p1.rating, p2.rating);
double e2 = 1.0 - e1; // expectedScore(p2.rating, p1.rating);
double s2 = 1.0 - score1;
p1.rating += kFactor * (score1 - e1);
p2.rating += kFactor * (s2 - e2);
}
int main() {
Player p1 = {"Player A", 1200};
Player p2 = {"Player B", 1000};
double K = 30;
cout << "Truoc tran: " << p1.name << "(" << p1.rating << ") vs "
<< p2.name << "(" << p2.rating << ")\n";
// Player A thắng
updateElo(p1, p2, K, 1.0);
cout << fixed << setprecision(2);
cout << "Sau tran (A thang): " << p1.name << "(" << p1.rating << ") vs "
<< p2.name << "(" << p2.rating << ")\n";
return 0;
}
Đầu ra
Truoc tran: Player A(1200) vs Player B(1000) Sau tran (A thang): Player A(1207.20) vs Player B(992.80)