在线联机原型全集:Elo 与 Glicko-2 评分系统详解
Elo 与 Glicko-2 评分系统详解
(Ranking & Matchmaking Rating Systems Deep Dive)
一、背景与意义(Background & Motivation)
在任何竞技型游戏中,无论是 PvP(如团队占点、射击)还是 PvE(排行榜挑战),都需要一个衡量玩家实力的量化模型。 目标是:
- 量化实力(Skill Estimation):让系统能知道谁强谁弱。
- 驱动匹配(Matchmaking):让匹配更公平(实力相近的玩家同场)。
- 驱动进步(Progression):让玩家看到成长(分数、段位)。
- 支撑赛制(Tournament/Season System):用于排名、奖励分配。
在长期的游戏史中,最经典的两套模型就是:
- Elo Rating System(艾洛体系)
- Glicko-2 Rating System(Glickman改进体系)
二、Elo 体系(Elo Rating System)
2.1 起源与原理
Elo 体系由匈牙利裔美国物理学家 Arpad Elo 于 1960 年代提出,最初用于国际象棋。 核心思想:玩家的评分代表其预期胜率,比赛结果与预期偏差越大,分数变化越大。
2.2 核心公式
(1)胜率预期(Expected Score)
对 A、B 两位选手:
[ E_A = \frac{1}{1 + 10^{(R_B - R_A)/400}} ] [ E_B = 1 - E_A ]
其中:
- ( R_A, R_B ):两人的 Elo 评分;
- ( E_A ):A 的期望得分(概率 0~1);
- 400 是常数,代表 400 分差≈胜率 10:1。
(2)实际得分(Actual Score)
- 胜利:( S = 1 )
- 平局:( S = 0.5 )
- 失败:( S = 0 )
(3)评分更新(Rating Update)
[ R’_A = R_A + K \times (S_A - E_A) ]
其中:
- ( K ):K 因子,代表调整速率(如 16、24、32 等);
- ( S_A - E_A ):实际与期望差异;
- 若 A 胜 B:( R_A ) 上升,( R_B ) 下降。
2.3 示例
| 玩家 | 初始分 | 比赛结果 | 新分 |
|---|---|---|---|
| A | 1500 | 胜 B(1600) | (1500 + 32*(1 - 0.359) = 1520.5) |
| B | 1600 | 负 A | (1600 + 32*(0 - 0.641) = 1579.5) |
A 胜强敌涨分较多,B 负弱者掉分较多。
2.4 特点
✅ 优点:
- 简单、直观、易于计算;
- 参数少(仅需 K);
- 可单场实时更新。
❌ 缺点:
- 未考虑不确定性(玩家活跃度差异);
- 多人/团队模式不够精确;
- 新人初始化不稳定;
- 不区分“久未参赛”的退化(Rating Decay)。
三、Glicko 体系(Glicko System)
3.1 改进动机
Mark Glickman(美国统计学家)提出 Glicko,认为 Elo 体系“只给出一个点估计”,但不说明置信度。
因此,他引入两个关键变量:
- RD(Rating Deviation):评分偏差,衡量不确定性;
- σ(Volatility):评分波动率,衡量玩家状态变化速度。
3.2 Glicko-1 概念(基础版)
(1)三个核心量:
- ( R ):当前评分;
- ( RD ):评分偏差;
- ( σ ):波动率(在 Glicko-1 固定为常数)。
RD 初始约 350,越小代表玩家实力越确定。
(2)基本思想
- 每局结束后,根据对手分数与偏差计算新的 ( RD’ );
- 久不参赛,( RD ) 会逐渐上升(系统“不再确定你多强”)。
3.3 Glicko-2 体系(进化版)
Glicko-2 在 2001 年提出,是当前最主流的竞技体系(LoL、CS2、Overwatch 等都基于变体)。 相较 Elo:
| 项目 | Elo | Glicko-2 |
|---|---|---|
| 不确定性 | 无 | 有(RD) |
| 状态波动 | 无 | 有(σ) |
| 多局批量更新 | 不支持 | 支持 |
| 新人适应 | 慢 | 快 |
| 退化机制 | 无 | 有(自动) |
3.4 Glicko-2 公式详解
以下使用 Glickman 官方符号(数学标准版)。
(1)变量定义
- ( r ):评分(以中值 1500 为中心)
- ( RD ):评分偏差
- ( σ ):波动率(0.05~0.35)
- ( q = \ln(10)/400 )
为简化计算,通常先将分数标准化: [ μ = (r - 1500) / 173.7178, \quad φ = RD / 173.7178 ]
(2)对每个对手 ( j ):
- 对手的评分 ( μ_j )
- 对手的偏差 ( φ_j )
- 比赛结果 ( s_j \in {0, 0.5, 1} )
计算修正因子: [ g(φ_j) = \frac{1}{\sqrt{1 + 3 q^2 φ_j^2 / π^2}} ]
预期得分: [ E(μ, μ_j, φ_j) = \frac{1}{1 + e^{-g(φ_j)(μ - μ_j)}} ]
(3)信息量(variance)
[ v = \left[ \sum_j g(φ_j)^2 E_j (1 - E_j) \right]^{-1} ]
(4)评分改变量 Δ
[ Δ = v \sum_j g(φ_j)(s_j - E_j) ]
(5)波动率更新(σ 更新)
波动率通过迭代法求出,解如下: [ f(x) = \frac{e^x(Δ^2 - φ^2 - v - e^x)}{2(φ^2 + v + e^x)^2} - \frac{x - \ln(σ^2)}{τ^2} ] 用二分或牛顿法求出新 ( σ’ )。
其中 ( τ ) 是波动率变化约束(通常 0.5)。
(6)新偏差 φ’(RD 更新)
[ φ’ = \frac{1}{\sqrt{\frac{1}{φ^2 + σ’^2} + \frac{1}{v}}} ]
(7)新评分 μ'
[ μ’ = μ + q φ’^2 \sum_j g(φ_j)(s_j - E_j) ]
(8)反标准化
[ r’ = 173.7178 × μ’ + 1500, \quad RD’ = 173.7178 × φ' ]
3.5 空闲衰减(Rating Decay)
若玩家长时间不参赛(周期长度 ( t )),其 RD 自动膨胀: [ RD_t = \sqrt{RD_0^2 + σ^2 t} ] 使得其评分置信度下降,重新参与时变化幅度会更大。
四、团队模式下的改进(Team Rating Models)
在 proto-012-team-domination 中,属于 2–3 队对抗,占点式团队赛,需要将个人 Elo/Glicko 扩展为团队。
4.1 团队 Elo(Team-Elo)
- 计算团队平均分 ( R_{team} = \frac{Σ R_i}{N} )
- 按 Elo 胜率公式计算团队期望值;
- 每个队员更新分数: [ R_i’ = R_i + K × w_i × (S - E) ] 其中 ( w_i ) 为参与度权重(如击杀、得分、在点时间)。
使“核心贡献者涨分多、挂机者涨分少”。
4.2 团队 Glicko-2
同样可以取团队平均 μ, φ 后,计算团队期望与 Δ。 每名玩家的更新权重按表现比重分配。 公式保持一致,仅把每局视为“团队 vs 团队”。
4.3 混合模式(Hybrid Rating)
对于 SLG / 团队塔防 / 占点类游戏,可采用:
-
Elo + 内部绩效系数(Skill = Rating × Performance)
-
或 Glicko2 + KPI加权,KPI 包括:
- 参与占点时间比例;
- 击杀/死亡比;
- 支援次数;
- 经济贡献。
最终: [ Δ_i = BaseΔ × \frac{P_i}{Σ P} ] 实现团队胜利共享,个人表现差异化奖励。
五、系统实现(Implementation in Server)
5.1 数据结构设计
CREATE TABLE player_rating (
player_id BIGINT PRIMARY KEY,
rating FLOAT DEFAULT 1500,
rd FLOAT DEFAULT 350,
volatility FLOAT DEFAULT 0.06,
last_match TIMESTAMP,
total_games INT DEFAULT 0
);
比赛结果日志:
CREATE TABLE match_result (
match_id BIGSERIAL PRIMARY KEY,
team_a_score INT,
team_b_score INT,
winner CHAR(1),
created_at TIMESTAMP DEFAULT now()
);
CREATE TABLE match_participant (
match_id BIGINT,
player_id BIGINT,
team CHAR(1),
performance FLOAT,
result FLOAT, -- 1/0.5/0
rating_before FLOAT,
rating_after FLOAT
);
5.2 服务端计算流程(伪代码)
func UpdateRatings(match MatchResult) {
teams := aggregateTeams(match.Participants)
// 1. 计算团队平均 rating, rd
for team in teams {
team.mu, team.phi = average(team.players)
}
// 2. 计算预期胜率
E_A := 1 / (1 + math.Pow(10, (teamB.mu - teamA.mu)/400))
E_B := 1 - E_A
// 3. 计算团队得分 S (1,0.5,0)
S_A, S_B := getResults(match)
// 4. 计算团队 Δ, v, σ'
deltaA := computeDelta(teamA, teamB, S_A, E_A)
sigmaA := updateVolatility(teamA, deltaA)
// 5. 更新每位成员 rating, rd
for player in teamA.players {
w := player.performance / teamA.totalPerf
player.rating = glickoUpdate(player, teamA, teamB, deltaA, sigmaA, w)
}
}
5.3 匹配算法(Matchmaking)
基于评分区间 ±RD 计算实力范围:
[ SkillRange = [R - 2×RD, R + 2×RD] ]
匹配时:
- 两队平均分差 ≤ 100;
- RD 差 ≤ 50;
- 允许根据等待时间逐步放宽(每 5s +20)。
六、可视化与段位划分(Rank Visualization)
为便于玩家理解,需要将抽象的数值映射为段位。
6.1 段位区间(例)
| 段位 | Elo 分数区间 | 说明 |
|---|---|---|
| 青铜 Bronze | 1000–1299 | 新人阶段 |
| 白银 Silver | 1300–1499 | 基础水平 |
| 黄金 Gold | 1500–1699 | 平均水平 |
| 铂金 Platinum | 1700–1899 | 高水平 |
| 钻石 Diamond | 1900–2099 | 顶级玩家 |
| 大师 Master | 2100+ | 极少数精英 |
Glicko-2 可使用 ( R - 2×RD ) 作为“保守评分”来决定段位,避免波动频繁。
6.2 可视化界面建议
- 进度条:显示距离下/上一级段位的分差;
- 置信度环:以 RD 大小表示稳定度;
- 波动动画:比赛后分数浮动曲线;
- 赛季面板:展示赛季最高分、稳定期、退化提示。
七、赛季与衰减机制(Seasons & Decay)
- 赛季周期:每 60~90 天清算;
- 软重置: [ R_{new} = 1500 + (R_{old} - 1500) × 0.75 ] ( RD_{new} = \min(350, RD_{old} × 1.5) )
- 退化机制:若 30 天未参赛,( RD += σ×30 );
- 赛季奖励:根据最高段位或平均分发放(称号/皮肤/货币)。
八、性能与扩展(Performance & Scaling)
| 项目 | Elo | Glicko-2 |
|---|---|---|
| 计算复杂度 | O(1) | O(n)(每场对手数量) |
| 存储 | rating | rating + rd + σ |
| 适合场景 | 快节奏、频繁对局 | 长期稳定竞技 |
在 proto-012-team-domination 场景中:
- 每场玩家≤16,Glicko-2 的性能完全可接受;
- 使用浮点缓存,周期性批量更新到数据库;
- 支持离线计算、夜间异步聚合(Daily Rating Job)。
九、日志与指标(Metrics)
| 指标名 | 含义 |
|---|---|
rating_change_mean |
平均涨跌幅 |
rd_mean |
平均置信区间 |
sigma_mean |
平均波动率 |
win_expect_accuracy |
胜率预测准确率 |
decay_triggered_total |
退化触发次数 |
season_reset_count |
赛季重置次数 |
十、实例分析:三场比赛演进
| 局次 | 对手分 | 胜负 | ΔR | 新评分 | RD | σ |
|---|---|---|---|---|---|---|
| 1 | 1600 | 胜 | +25 | 1525 | 340 | 0.06 |
| 2 | 1550 | 胜 | +15 | 1540 | 320 | 0.06 |
| 3 | 1700 | 负 | −10 | 1530 | 300 | 0.06 |
可见随着 RD 下降,分数波动变小——系统对玩家实力越来越有信心。
十一、服务端与日志一体化架构图
graph TD
A[Match Result Engine] --> B[Rating Update Service]
B --> C[Player DB (rating, rd, sigma)]
B --> D[Match Logs (performance, details)]
C --> E[Matchmaker]
E --> A
C --> F[Analytics / Leaderboard]
F --> G[Season Reset Job]
数据闭环:比赛结果 → 评分更新 → 匹配优化 → 排行榜 → 赛季清算。
十二、常见问题(FAQ)
| 问题 | 答案 |
|---|---|
| Elo 与 MMR 有区别吗? | MMR 是广义术语(MatchMaking Rating),Elo/Glicko 是具体算法。 |
| 如何防止“逃跑”影响? | 逃跑计为失败,且额外惩罚(ΔR×1.5)。 |
| 是否可以隐藏评分? | 可设“内部 MMR”(匹配用)与“可见段位”分离。 |
| 组队如何计算? | 使用队伍平均 + 协作权重分配 ΔR。 |
| 新玩家初始化? | rating=1500, rd=350, σ=0.06;快速收敛期 K 因子加大。 |