在线联机原型全集:第 12 章 Elo 与 Glicko-2 评分系统详解

第 12 章:Elo 与 Glicko-2 评分系统详解,介绍了 Elo 与 Glicko-2 评分系统的原理、公式、应用场景,以及在团队占点游戏中的实际效果。

Elo 与 Glicko-2 评分系统详解

(Ranking & Matchmaking Rating Systems Deep Dive)


一、背景与意义(Background & Motivation)

在任何竞技型游戏中,无论是 PvP(如团队占点、射击)还是 PvE(排行榜挑战),都需要一个衡量玩家实力的量化模型。
目标是:

  1. 量化实力(Skill Estimation):让系统能知道谁强谁弱。
  2. 驱动匹配(Matchmaking):让匹配更公平(实力相近的玩家同场)。
  3. 驱动进步(Progression):让玩家看到成长(分数、段位)。
  4. 支撑赛制(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 示例

玩家初始分比赛结果新分
A1500胜 B(1600)(1500 + 32*(1 - 0.359) = 1520.5)
B1600负 A(1600 + 32*(0 - 0.641) = 1579.5)

A 胜强敌涨分较多,B 负弱者掉分较多。

2.4 特点

✅ 优点:

  • 简单、直观、易于计算;
  • 参数少(仅需 K);
  • 可单场实时更新。

❌ 缺点:

  • 未考虑不确定性(玩家活跃度差异);
  • 多人/团队模式不够精确;
  • 新人初始化不稳定;
  • 不区分“久未参赛”的退化(Rating Decay)。

三、Glicko 体系(Glicko System)

3.1 改进动机

Mark Glickman(美国统计学家)提出 Glicko,认为 Elo 体系“只给出一个点估计”,但不说明置信度

因此,他引入两个关键变量:

  1. RD(Rating Deviation):评分偏差,衡量不确定性;
  2. σ(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:

项目EloGlicko-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 分数区间说明
青铜 Bronze1000–1299新人阶段
白银 Silver1300–1499基础水平
黄金 Gold1500–1699平均水平
铂金 Platinum1700–1899高水平
钻石 Diamond1900–2099顶级玩家
大师 Master2100+极少数精英

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)

项目EloGlicko-2
计算复杂度O(1)O(n)(每场对手数量)
存储ratingrating + 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σ
11600+2515253400.06
21550+1515403200.06
31700−1015303000.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 因子加大。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页