CS221 · 人工智能:原理与技术
Lecture 11 · 博弈 II:TD 学习与同时博弈
源文件:lecture-11.md
Lecture 11 · 博弈 II:TD 学习与同时博弈
CS221: Artificial Intelligence — Principles and Techniques · Stanford · Autumn 2025
📅 Oct 27 · 💻td_learning.py·simultaneous_games.py
从手工启发式到自我对弈
上一讲(Lecture 10 · 博弈 I:Minimax 与 α-β 剪枝):我们把两人零和博弈形式化为游戏树,用 minimax / expectimax / expectiminimax 三种递归给局面定价;为了对付指数级的树,引入了两个加速手段——α-β 剪枝(精确,只跳过不可能影响答案的子树)与评估函数 + 深度受限搜索(近似,用先验知识给中间局面打分)。遗留问题:评估函数是人手工写的启发式(子力分 + 位置分 + 机动性……),既费人力又难以超越设计者的棋理。
本讲(博弈 II)分成两大块:
- 第一部分(TD 学习):能不能把评估函数学出来?用强化学习估计状态价值 $V_\pi(s)$,并让程序自我对弈(self-play)自己生成训练数据、自己变强——这条路从 Samuel 跳棋通向 TD-Gammon 与 AlphaGo。
- 第二部分(同时博弈):放开”回合制”假设,研究双方同时出手的博弈(石头剪刀布、two-finger Morra)。游戏树失效,引出混合策略、minimax 定理与纳什均衡。
说明
两部分共享「博弈」这个主题,但技术上几乎独立:第一部分是「学习 + 回合制博弈」(承接 Lecture 8 · 强化学习 与 Lecture 9 · 函数逼近与策略梯度),第二部分是「同时博弈的博弈论」。分开读即可。
第一部分 · TD 学习:学习评估函数
1. 动机:为什么要「学」评估函数?
1.1 回顾:minimax 与评估函数
上一讲的核心是 minimax:己方取 $\max$,对手取 $\min$,在游戏树上递归。游戏树太深无法走到底,于是在某个深度截断,用评估函数 $\mathrm{Eval}(s)$ 估计当前局面的好坏。
graph TD
A["s(轮到 agent)"] -->|"max_a"| B["s'(轮到对手)"]
B -->|"min_b"| C["s''"]
C -.->|"深度耗尽"| E["评估函数<br/>Eval(s)"]
style A fill:#c8e6c9,stroke:#2e7d32
style B fill:#ffcdd2,stroke:#c62828
style E fill:#ffe0b2,stroke:#e65100
问题:$\mathrm{Eval}(s)$ 一直是人手工设计的启发式(如国际象棋的「子力价值 + 棋子位置」)。手工设计有两个硬伤:需要深厚的领域知识(换一个游戏就得重来),而且天花板就是设计者自己的理解。能不能让机器自己学出这个评估函数?
1.2 关键类比:TD 学习 : $V_\pi$ :: SARSA : $Q_\pi$
这是理解本讲第一部分的钥匙。先把 Lecture 8 · 强化学习 的两个价值函数摆出来:
| 记号 | 含义 |
|---|---|
| $V_\pi(s)$ | 从状态 $s$ 出发、此后遵循策略 $\pi$ 的期望效用(状态有多好) |
| $Q_\pi(s, a)$ | 在 $s$ 先执行动作 $a$、此后遵循 $\pi$ 的期望效用(动作有多好) |
L8 里的 SARSA 用自举(bootstrapping)估计 $Q_\pi(s, a)$。本讲的 TD 学习(temporal difference learning,时序差分学习) 用同样的思路估计 $V_\pi(s)$:
说明
$$\text{TD learning} : V_\pi \;::\; \text{SARSA} : Q_\pi$$
SARSA 告诉你「每个动作有多好」;TD 学习告诉你「每个状态有多好」。评估函数要回答的恰恰是后者——“这个局面值多少分”。
1.3 只知道 $V_\pi(s)$,如何读出策略?
有了 Q 值,读出更好的策略很自然(策略改进 policy improvement):
$$\pi_{\text{new}}(s) = \arg\max_a Q_\pi(s, a)$$
那如果只有 $V_\pi(s)$ 呢?回顾 MDP 里 $V$ 与 $Q$ 的关系:
$$V_\pi(s) = Q_\pi(s, \pi(s)),\qquad Q_\pi(s, a) = \sum_{s'} T(s, a, s')\,\big[R(s, a, s') + \gamma\, V_\pi(s')\big]$$
其中 $T(s,a,s')$ 是转移概率,$R(s,a,s')$ 是即时奖励,$\gamma$ 是折扣因子。代入即得从 $V$ 读出策略的公式:
$$\pi_{\text{new}}(s) = \arg\max_a \sum_{s'} T(s, a, s')\,\big[R(s, a, s') + \gamma\, V_\pi(s')\big]$$
注意
这一步需要知道 MDP(转移 $T$、奖励 $R$)!因为要「往前看一步」,把每个动作展开成后继分布才能比较。SARSA 用 Q 值读策略时不需要模型(Q 已经替你把”往前看一步”折进去了),而 TD 学习用 V 值时必须借助模型做这步 $\arg\max$。这是「估计 V」比「估计 Q」便宜(少一个动作维度)所付出的代价。
但在博弈里,我们恰好知道 $T$ 和 $R$!——游戏规则完全已知。而且博弈的「动作 → 下一状态」是确定性的(我落一子,棋盘状态就唯一确定),上式大幅简化:
$$\pi_{\text{new}}(s) = \arg\max_a V_\pi\big(\mathrm{Succ}(s, a)\big)$$
其中 $\mathrm{Succ}(s, a)$ 是在 $s$ 执行动作 $a$ 后确定到达的后继状态。只要知道每个后继局面有多好,就能直接选出最好的一步。 这正是「学评估函数」的意义:学到的 $V_\pi$ 就是一个可以直接用来下棋的 $\mathrm{Eval}$。
1.4 为什么用 RL,而不是价值迭代?
一个自然的反问:
「既然博弈里我们已经知道 MDP(规则完全已知),为什么不直接用价值迭代求解,非要用强化学习?」
答案:因为状态数是指数级的,价值迭代根本存不下、算不动。
- 国际象棋约 $10^{45}$ 个局面,围棋约 $10^{170}$ 个;
- 价值迭代要为每个状态存一个 $V(s)$ 并反复全表扫描——在这种规模下不可能。
提示
这是一个重要的视角转变。Lecture 8 · 强化学习 用 RL 是因为 MDP 未知(转移/奖励是黑盒,只能靠试);本讲用 RL 不是因为未知,而是因为状态空间太大——必须用函数逼近 $V(s; \mathbf{w})$ 把天文数字个状态压缩进一组参数里,并且只从采样到的经验(实际下出来的对局)学习,而不是遍历所有状态。同一个算法,两种完全不同的使用理由。
flowchart LR
A["博弈 MDP<br/>规则已知"] --> B{"状态数?"}
B -->|"少"| C["价值迭代<br/>逐状态精确解"]
B -->|"指数级<br/>(棋类)"| D["强化学习<br/>+ 函数逼近 V(s;w)"]
style C fill:#e3f2fd,stroke:#1976d2
style D fill:#c8e6c9,stroke:#2e7d32
2. TD 学习算法
2.1 函数逼近:价值网络
不再为每个状态存表,而是用带参数的函数逼近价值:
$$V_\pi(s) \approx V(s; \mathbf{w})$$
其中 $\mathbf{w}$ 是待学习的权重向量。这与 Lecture 9 · 函数逼近与策略梯度 里 Q-learning 的函数逼近是同一招,只是套在 $V$ 上。
说明
在深度强化学习里,$V(s; \mathbf{w})$ 就叫价值网络(value network)。它可以是线性的 $\phi(s) \cdot \mathbf{w}$($\phi(s)$ 为特征向量),也可以是一个 MLP / 深度网络。AlphaGo 论文里的 value network 就是这个对象。
2.2 核心思路:自举 + 平方损失 + 梯度步
TD 学习从一条条经验 $(s, a, r, s')$(当前状态、动作、即时奖励、下一状态)中在线更新权重 $\mathbf{w}$,五步一循环:
- 拿到一段经验 $(s, a, r, s')$;
- 模型预测:$V(s; \mathbf{w})$;
- 构造自举目标(bootstrap target):$r + \gamma\, V(s'; \mathbf{w})$;
- 平方损失:$$\mathcal{L}(\mathbf{w}) = \Big(V(s; \mathbf{w}) - \big(r + \gamma\, V(s'; \mathbf{w})\big)\Big)^2$$
- 梯度步:$\mathbf{w} \leftarrow \mathbf{w} - \alpha\, \nabla_{\mathbf{w}} \mathcal{L}(\mathbf{w})$,其中 $\alpha$ 是学习率。
直觉:让「当前状态的预测」向「即时奖励 + 下一状态的(估计)价值」靠拢。目标里用到了 $V$ 自己($V(s')$),这就是自举——用一个估计去改进另一个估计,与 L7 策略评估、L8 SARSA 一脉相承。两者的差 $$\delta = r + \gamma\, V(s'; \mathbf{w}) - V(s; \mathbf{w})$$ 称为 TD 误差(TD error):$\delta > 0$ 说明实际比预期好(上调 $V(s)$),$\delta < 0$ 说明比预期差(下调)。
注意
求梯度时,目标 $r + \gamma V(s'; \mathbf{w})$ 中的 $\mathbf{w}$ 按惯例视为常数(不对它求导),只对预测项 $V(s;\mathbf{w})$ 求导——这叫半梯度(semi-gradient)更新。线性情形下更新有干净的形式:$\mathbf{w} \leftarrow \mathbf{w} + \alpha\,\delta\,\phi(s)$。表格版是它的特例($\phi$ 为 one-hot):$V(s) \leftarrow V(s) + \alpha\,\delta$。
对比 L8 的无模型算法家族,TD 学习填上了「估计 V」这一格:
| 算法 | 估计对象 | 自举目标 | 读策略是否需模型 |
|---|---|---|---|
| SARSA | $Q_\pi$ | $r + \gamma\, Q(s', a')$ | 否 |
| Q-Learning | $Q^*$ | $r + \gamma \max_{a'} Q(s', a')$ | 否 |
| TD 学习 | $V_\pi$ | $r + \gamma\, V(s')$ | 是 |
提示
TD 学习和 SARSA 一样是 on-policy 的:它估计的是「当前这套策略走下去」的价值,目标里只用到实际走出的下一状态 $s'$,不去看其他动作。这正合博弈的用法——我们要评估的就是”照当前棋力下完这盘”的胜率,然后再用它改进棋力,循环往复。
2.3 源码:TDLearning 类
以下是 td_learning.py 中的真实实现(加了中文注释)。注意它复用了 L8 的 RLAlgorithm 接口(get_action + incorporate_feedback)。这里为了在小 MDP 上演示,V 用的是 defaultdict(表格版);把它换成 $V(s;\mathbf{w})$ 就是函数逼近版。
class TDLearning(RLAlgorithm):
"""实现 TD 学习算法。"""
def __init__(self, mdp: MDP, exploration_policy: Policy,
epsilon: float, discount: float, learning_rate: float):
self.mdp = mdp # 需要 MDP 来读出策略!
self.exploration_policy = exploration_policy
self.epsilon = epsilon # ε-贪婪探索
self.discount = discount # 折扣 γ
self.learning_rate = learning_rate # 学习率 α
self.V = defaultdict(float) # 状态价值 V_π(s)
def get_action(self, state: Any) -> Any:
"""用 MDP 从 V_π(s) 计算 Q_π(s, a),再 ε-贪婪选动作。"""
if np.random.random() < self.epsilon:
return self.exploration_policy(state) # 探索
else:
return self.pi(state) # 利用
def pi(self, state: Any) -> Any:
"""返回当前 V_π(s) 对应的策略:argmax_a V(Succ(s,a))。"""
# 为每个动作计算 Q 值(唯一用到 MDP 知识的地方)
q_values = {} # action -> Q 值
for action, successors in get_action_successors(self.mdp, state).items():
q_values[action] = sum(
succ.prob * (succ.reward + self.discount * self.V[succ.state])
for succ in successors
)
# 选 Q 值最大的动作
return max(q_values.keys(), key=lambda action: q_values[action])
def incorporate_feedback(self, state: Any, action: Any, reward: Any,
next_state: Any, is_end: bool) -> None:
"""根据经验 (s, a, r, s') 更新 V_π(s)。"""
predicted = self.V[state] # 预测
target = reward + self.discount * self.V[next_state] # 自举目标
self.V[state] += self.learning_rate * (target - predicted) # 梯度步
说明
看 incorporate_feedback 的最后一行:$V(s) \leftarrow V(s) + \alpha\,(\text{target} - \text{predicted})$,括号里正是 TD 误差 $\delta$。这是平方损失对表格项 $V(s)$ 求导后的随机梯度下降——和 L8 里 SARSA 更新 Q 的形式一模一样,只是把 $Q(s,a)$ 换成了 $V(s)$。另外注意 pi 方法:self.mdp 只在读策略时用到,更新 V 本身不需要模型。
2.4 在 flaky tram 上跑一遍
沿用 Lecture 7 · 马尔可夫决策过程 的不可靠电车 MDP(FlakyTramMDP:走路确定 +1 站、坐电车翻倍但有概率故障)喂一条轨迹,观察 V 被逐条经验推着更新:
mdp = FlakyTramMDP(num_locs=6, failure_prob=0.1)
policy = partial(walk_tram_policy, 6)
# 注意:TDLearning 需要 mdp 来计算策略(做 policy improvement)
rl = TDLearning(mdp=mdp, exploration_policy=policy,
epsilon=0.2, discount=1, learning_rate=0.1)
rl.get_action(state=1)
rl.incorporate_feedback(state=1, action="walk", reward=-1, next_state=2, is_end=False)
rl.get_action(state=2)
rl.incorporate_feedback(state=2, action="walk", reward=-1, next_state=3, is_end=False)
rl.get_action(state=3)
rl.incorporate_feedback(state=3, action="tram", reward=-2, next_state=6, is_end=True)
每条 incorporate_feedback 都把 $V(s)$ 朝 $r + \gamma V(s')$ 挪一小步(步长 $\alpha=0.1$)。跑足够多轨迹后,$V$ 收敛到当前探索策略的 $V_\pi$。
小结(TD 学习):从经验 $(s, a, r, s')$ 估计 $V_\pi(s)$;on-policy(只沿当前策略实际走出的转移学习);用自举(目标含 $V(s')$);读出策略时需要模型(博弈中天然满足)。
3. 把 TD 学习用到博弈上
3.1 从任意 MDP 到博弈
TD 学习对任意 MDP 都成立。适配到两人零和博弈只需注意三点:$\mathrm{Succ}(s, a)$ 确定性地刻画状态转移(落子即定);游戏中途没有奖励,只有终局才有效用(赢 $+1$ / 输 $-1$,且通常 $\gamma = 1$)——所以价值信号要靠 TD 更新从终局一步步”倒灌”回中盘与开局;有两个玩家(agent 与 opponent),需要说明对手从哪来——这就是自我对弈。
3.2 自我对弈(self-play)
关键技巧:双方共用同一个价值函数 $V_\pi(s)$,但取向相反——agent 挑价值最大的后继,对手挑价值最小的后继:
$$\pi_{\text{agent}}(s) = \arg\max_a V_\pi\big(\mathrm{Succ}(s, a)\big),\qquad \pi_{\text{opp}}(s) = \arg\min_a V_\pi\big(\mathrm{Succ}(s, a)\big)$$
零和博弈里这不浪费——一个 $V$(站在 agent 视角)同时刻画了双方的利害,对手的”最好”就是它的”最小”。
flowchart LR
V["共享价值函数<br/>V(s; w)"] --> AG["π_agent = argmax<br/>Succ(s,a)"]
V --> OP["π_opp = argmin<br/>Succ(s,a)"]
AG -->|"对弈产生经验"| EXP["(s, a, r, s')"]
OP -->|"对弈产生经验"| EXP
EXP -->|"TD 更新 w"| V
style V fill:#ffe0b2,stroke:#e65100
style AG fill:#c8e6c9,stroke:#2e7d32
style OP fill:#ffcdd2,stroke:#c62828
style EXP fill:#e1f5fe,stroke:#0277bd
提示
自我对弈:程序左右手互搏,用同一个 $V$ 既当自己又当对手。对弈产生经验,经验用来 TD 更新 $V$,更强的 $V$ 又产生更强的对弈——正反馈循环让棋力螺旋上升。妙处有二:① 不需要人类对局数据,训练数据无限自产;② 对手强度始终与自己匹配(永远棋逢对手),课程难度自动递增。这是 TD-Gammon 与 AlphaGo Zero 的共同灵魂,也与 CS336 里 LLM 的 RLVR 训练(Lecture 16 · 对齐 II:RLVR(未找到对应页面))遥相呼应——都是”自己生成数据、按结果信号改进自己”。
3.3 例子:西洋双陆棋(Backgammon)
双陆棋是带随机性(掷骰子)的双人博弈。rollout 时策略与骰子交替出场:
$$\pi_{\text{dice}} \to \pi_{\text{agent}} \to \pi_{\text{dice}} \to \pi_{\text{opp}} \to \pi_{\text{dice}} \to \pi_{\text{agent}} \to \cdots$$
我们要学的是 $\pi_{\text{agent}}$ 和 $\pi_{\text{opp}}$(同一个 $V$ 的两副面孔),而 $\pi_{\text{dice}}$(骰子)是固定的随机环境,不用学。这正是上一讲 expectiminimax 场景(Lecture 10 · 博弈 I:Minimax 与 α-β 剪枝 §2.4)的学习版。
参数化价值函数:先为每个局面定义特征向量 $\phi(s)$(如各点位上双方棋子的数量),再定义
$$\text{线性:}\; V(s; \mathbf{w}) = \phi(s) \cdot \mathbf{w}\qquad\text{或 MLP:}\; V(s; \mathbf{w}) = \mathrm{MLP}_{\mathbf{w}}\big(\phi(s)\big)$$
然后直接套用 §2 的 TD 学习即可——算法一行不用改。
4. 历史里程碑
TD 学习 + 自我对弈是 AI 博弈史上最漂亮的一条线。从 Samuel 到 AlphaGo Zero 的趋势非常清晰:人手工注入的领域知识越来越少(特征越来越「笨」,从精心设计的棋理特征退化到几乎原始的棋盘编码),而自我对弈 + 神经网络承担的比重越来越大。
| 系统 | 特征 | 评估函数 | 中途奖励 | 训练 |
|---|---|---|---|---|
| Samuel 跳棋 (1959) | 精心设计的特征 | 线性 | 有 | 自我对弈 + α-β 剪枝,达业余水平(IBM 701,约 9K 内存) |
| TD-Gammon (1992) | 「笨」特征(近乎原始棋盘编码) | 神经网络 | 无 | 自我对弈约 100 万局,达人类专家水平 |
| AlphaGo Zero (2017) | 「笨」特征(棋子位置) | 深度网络 | 无 | 自我对弈约 490 万局 + MCTS,击败 AlphaGo(后者 2016 年胜李世石) |
说明
三个补充:”机器学习(machine learning)”这个词正是 Samuel 在 1959 年那篇跳棋论文里创造的;TD-Gammon 甚至给人类玩家带来了全新的开局理论——机器反过来教会了人类;AlphaGo Zero 在价值网络之外还引入了策略网络与蒙特卡洛树搜索(MCTS),用搜索增强学习信号,但”自我对弈 + 学出来的评估”这条主线与 TD-Gammon 一脉相承。
第二部分 · 同时博弈
5. 从回合制到同时出手
上一讲的博弈都是回合制(turn-based):一方走完另一方再走,所以可以画出游戏树、逐层交替取 $\max$ / $\min$。
现在换成同时博弈(simultaneous games):两名玩家同一时刻出手,谁也看不到对方这一步。例子:石头剪刀布、two-finger Morra(两指莫拉)。
注意
游戏树失效了!树结构隐含”后走的人看得见先走的人做了什么”——每个节点都以到达它的历史为条件。同时博弈里没有”先后”,无法再用「我走这步之后对手最优应对」的方式递归——双方的决策相互纠缠、互为条件。需要一套新的解概念。
灵魂拷问(课上 Poll):如果你公开自己的策略,还能打得同样好吗?直觉说不行——石头剪刀布里固定出石头(纯策略)一旦被知道,对手立刻用布克制。但本部分的高潮(§8.4)会证明:只要允许混合策略,公开你的最优策略一点也不吃亏。
本部分结构:先零和(§6–§8),再非零和(§9)。
6. 单步同时博弈:定义
以 two-finger Morra 为例:两名玩家 A、B 同时伸出 1 根或 2 根手指。
说明
- 两名玩家 A 和 B;
- 收益矩阵(payoff matrix) $V(a, b)$:对每个动作对 $(a, b)$ 给出一个数;
- 零和:A 的效用是 $V(a, b)$,B 的效用是 $-V(a, b)$;
- 注意:没有状态、没有序列,一人只出一个动作(单步)。这是最小可研究单元,却已足够呈现同时博弈的全部核心现象。
Morra 的收益矩阵(行是 A 的动作,列是 B 的动作,数值是 A 的收益):
| A \ B | B 出 1 | B 出 2 |
|---|---|---|
| A 出 1 | +2 | −3 |
| A 出 2 | −3 | +4 |
actions = [1, 2]
V = {
1: {1: 2, 2: -3},
2: {1: -3, 2: 4},
}
直觉:A 想和 B 出一样多的手指(对角线为正),且偏爱凑成总和 4(右下的 +4 最大);B 则相反,想让手指数错开(反对角线上 A 拿 −3,即 B 拿 +3)。
7. 纯策略 vs 混合策略
说明
- 纯策略(pure strategy):确定性地出某个单一动作 $a$;
- 混合策略(mixed strategy):动作上的概率分布 $\pi(a)$,每次按分布随机抽一个动作。纯策略是混合策略把全部概率压在一个动作上的特例。
Morra 里的几个策略:
always_one = {1: 1.0} # π = [1, 0] 总出 1
always_two = {2: 1.0} # π = [0, 1] 总出 2
uniform = {1: 0.5, 2: 0.5} # π = [0.5, 0.5] 五五开
博弈评估(game evaluation):给定双方(混合)策略,A 的期望收益是
$$V(\pi_A, \pi_B) = \sum_a \sum_b \pi_A(a)\, \pi_B(b)\, V(a, b)$$
即对所有动作组合 $(a,b)$,按两人独立随机选中它的概率 $\pi_A(a)\pi_B(b)$ 加权求和。源码里就是一个双重循环:
def evaluate_game(V, policy_a, policy_b):
"""计算博弈的期望效用。"""
value = 0
for a, prob_a in policy_a.items():
for b, prob_b in policy_b.items():
value += prob_a * prob_b * V[a][b]
return value
例子
evaluate_game(V, uniform, uniform):四个格子各占 $0.25$,$0.25 \times (2 - 3 - 3 + 4) = 0$——双方都五五开时博弈值为 0,看似”公平”。但下面会看到,这不是均衡:双方都还有更好的选择,而真正的均衡值并不是 0。
8. minimax 定理
8.1 同时最优的困境与「先走者劣势」
博弈值 $V(\pi_A, \pi_B)$:A 想最大化、B 想最小化,而且要同时决定——像十字路口两车对峙,互相等对方先动,谁也不敢先动(deadlock)。
破局思路:既然”同时”难分析,干脆让一方先亮出策略、另一方看到后再应对,把问题变回有先后的序贯决策;然后比较”A 先亮”与”B 先亮”两种次序的结果。
先看纯策略:若 A 被迫先亮出纯策略,B 看到后必能针对性克制——Morra 里 A 亮 always_one,B 出 2,A 拿 $-3$;A 亮 always_two,B 出 1,A 还是拿 $-3$。结论:
注意
后走者不吃亏,甚至占便宜(the second player is no worse off)。先亮出纯策略等于暴露全部信息,被对手精确克制——这似乎印证了”策略必须保密”的直觉。
8.2 引入混合策略:后走者的最优应对
现在让 A 先亮出一个混合策略,比如 $\pi_A = [0.5, 0.5]$,看 B 如何最优应对。把博弈值按 B 的两个纯动作展开:
$$V(\pi_A, \pi_B) = \pi_B(1)\underbrace{\big[0.5(2) + 0.5(-3)\big]}_{-0.5} + \pi_B(2)\underbrace{\big[0.5(-3) + 0.5(4)\big]}_{+0.5} = -0.5\,\pi_B(1) + 0.5\,\pi_B(2)$$
B 想最小化 → 把全部概率压到系数更小的动作上:$\pi_B(1) = 1$,A 拿 $-0.5$。注意这已经比亮纯策略的 $-3$ 好多了——随机化本身就在保护你。
提示
关键观察:后走的玩家总可以用纯策略应对。因为博弈值对 $\pi_B$ 是线性的(固定 $\pi_A$ 后,它是 $\pi_B$ 各分量的加权和),线性函数在单纯形上的最小值必在顶点(某个纯动作)取到——混合不会更优。这一步把”对手的最优应对”从无穷维搜索压缩成了有限枚举。
一般地,设 A 先亮 $\pi_A = [p,\, 1-p]$,B 分别用两个纯动作应对时 A 的收益是:
$$\text{B 出 1}:\; 2p - 3(1-p) = 5p - 3,\qquad \text{B 出 2}:\; -3p + 4(1-p) = 4 - 7p$$
B 取两者的最小值(下包络),A 再对 $p$ 取最大(下包络的最高点)——这就是「A 先走」的 $\max\min$ 值。反过来让 B 先亮 $\pi_B$,同理得「B 先走」的 $\min\max$ 值。
8.3 minimax 定理:先后手价值相等
神奇之处:让 A 先亮和让 B 先亮,算出来的博弈值相等!
说明
对任意二人零和博弈(有限动作集),只要允许混合策略:
$$\max_{\pi_A} \min_{\pi_B} V(\pi_A, \pi_B) = \min_{\pi_B} \max_{\pi_A} V(\pi_A, \pi_B)$$
交换 $\max$ / $\min$ 的顺序不改变博弈值。先手劣势消失了——这个共同的值称为博弈值(value of the game)。
- 证明:线性规划对偶性(LP duality)——“A 先走”和”B 先走”恰好是一对互为对偶的 LP;
- 算法:最优混合策略可用线性规划求解(两动作情形可像下面一样手算)。
graph LR
subgraph 纯策略
P1["先走者暴露<br/>→ 劣势"]
end
subgraph 混合策略
M1["max min = min max<br/>先后手等价"]
end
P1 -->|"允许随机化"| M1
style P1 fill:#ffcdd2,stroke:#c62828
style M1 fill:#c8e6c9,stroke:#2e7d32
例子
A 亮 $[p, 1-p]$ 后,B 的两个纯应对给 A 的收益分别是 $5p-3$ 与 $4-7p$。A 要最大化两者的最小值;最优点在两条直线相交处(否则总可以往低的一侧挪一点 $p$ 换取提升):
$$5p - 3 = 4 - 7p \;\Longrightarrow\; 12p = 7 \;\Longrightarrow\; p = \tfrac{7}{12}$$
代回得博弈值 $5 \cdot \tfrac{7}{12} - 3 = -\tfrac{1}{12}$。由对称的推导,B 的最优混合策略同样是 $[\tfrac{7}{12}, \tfrac{5}{12}]$。
$$\pi_A^* = \pi_B^* = \Big[\tfrac{7}{12},\; \tfrac{5}{12}\Big],\qquad V(\pi_A^*, \pi_B^*) = -\tfrac{1}{12}$$
注意博弈值是负的:two-finger Morra 看似对称,其实对 B(求错开的一方)有利——A 每局平均要亏 $\tfrac{1}{12}$。”双方五五开时值为 0”只是假象,因为五五开不是均衡。
V = { 1: {1: 2, 2: -3},
2: {1: -3, 2: 4} }
pi_opt = {1: 7/12, 2: 5/12} # A、B 的最优混合策略相同
value = evaluate_game(V, pi_opt, pi_opt) # = -1/12 ≈ -0.083
8.4 Upshot:公开最优混合策略也不吃亏
说明
公开你的最优混合策略,不会让你变差(revealing your optimal mixed strategy doesn’t hurt you)。
这正好回答了 §5 的 Poll:因为 $\max\min = \min\max$,即使对手事先知道你的最优混合策略,他能做到的最好也只是把你压到博弈值——不能更多。需要保密的只是每一局具体抽到的动作(随机性本身),而不是生成动作的分布。
提示
站在最优策略对 $(\pi_A^*, \pi_B^*)$ 上:
- 如果对手单方面改变策略,你的收益只会变好或不变(对手放弃了对你的最优压制);
- 如果你单方面改变策略(偏离最优),你的收益只会变差或不变。
谁都没有单方面偏离的动机——这正是「均衡」的味道,也为 §9 的纳什均衡做了铺垫。另外注意 $p = \tfrac{7}{12}$ 恰好让 B 的两个纯应对收益相等(indifference,无差异原则):最优混合策略的本质就是”调配概率,让对手怎么应对都一样”,从而无懈可击。
9. 非零和博弈与纳什均衡
9.1 从零和到非零和
- 零和:$U_A + U_B = 0$,一方所得即另一方所失,纯粹竞争;
- 非零和(non-zero-sum):双方效用任意,可能双赢也可能双输。
效用关系构成一个谱系:一端是纯竞争(零和,用 minimax / 线性规划求解),另一端是纯合作(双方效用完全相同,退化成普通的联合最大化/搜索),现实生活大多介于两者之间。
非零和时每个玩家各有一张收益矩阵:记 $V_p(\pi_A, \pi_B)$ 为策略对下玩家 $p \in \{A, B\}$ 的期望效用(零和时只需一张,因为 $V_B = -V_A$)。
9.2 囚徒困境
经典的囚徒困境(prisoner’s dilemma):两名嫌犯分开审讯,可选沉默或招供;效用 $=-$(服刑年数)。
| A \ B | B 沉默 | B 招供 |
|---|---|---|
| A 沉默 | (−1, −1) | (−15, 0) |
| A 招供 | (0, −15) | (−10, −10) |
(每格为 (A 的效用, B 的效用);数值为示意,结构才是重点。)
困境:对每个人来说,无论对方怎么选,招供都严格更优——对方沉默时招供把 $-1$ 变 $0$,对方招供时招供把 $-15$ 变 $-10$。招供是严格优势策略(strictly dominant strategy) → 双方都招供,各判 10 年。但若两人都能沉默,本可只判 1 年——个体理性导致集体次优。问题出在两人无法缔结可信承诺:即使约好都沉默,各自仍有偏离的动机。
9.3 纳什均衡
零和世界的 von Neumann minimax 定理不再适用(它的证明本质依赖”你的所得就是我的所失”这一 LP 对偶结构)。退一步,我们得到一个更弱但更普适的解概念:
说明
一组策略 $(\pi_A^*, \pi_B^*)$,使得任何一方单方面改变策略都不会让自己变好:
$$V_A(\pi_A, \pi_B^*) \le V_A(\pi_A^*, \pi_B^*)\;\; \forall \pi_A,\qquad V_B(\pi_A^*, \pi_B) \le V_B(\pi_A^*, \pi_B^*)\;\; \forall \pi_B$$
没有人有偏离的动机 → 稳定。注意定义里只有”稳定”,没有”最优”。
说明
任何有限玩家、有限动作的博弈,都至少存在一个纳什均衡(可能是混合策略)。囚徒困境说明均衡可以是纯策略;石头剪刀布说明有些博弈的均衡只能是混合策略。
几个例子:
| 博弈 | 纳什均衡 |
|---|---|
| 竞争 Morra(零和) | 双方 $[\tfrac{7}{12}, \tfrac{5}{12}]$(同时也是 minimax 策略) |
| 合作 Morra(双方效用相同) | 双方同出 1,或双方同出 2(两个均衡) |
| 囚徒困境 | 双方都招供(唯一均衡,但非社会最优) |
9.4 零和 vs 非零和:一张对照
graph TD
A["同时博弈"] --> B["零和"]
A --> C["非零和"]
B --> B1["von Neumann<br/>minimax 定理"]
B --> B2["多个 minimax 策略<br/>单一博弈值"]
C --> C1["Nash<br/>存在性定理"]
C --> C2["多个纳什均衡<br/>多个博弈值"]
style B fill:#e1f5fe,stroke:#0277bd
style C fill:#f3e5f5,stroke:#7b1fa2
style B1 fill:#c8e6c9,stroke:#2e7d32
style C1 fill:#ffe0b2,stroke:#e65100
| 维度 | 零和同时博弈 | 非零和同时博弈 |
|---|---|---|
| 核心定理 | von Neumann minimax (1928) | Nash 存在性 (1950) |
| 解的性质 | 最优性(对最坏对手的保证) | 稳定性(无单方偏离动机) |
| 博弈值 | 唯一 | 可能多个(不同均衡不同值) |
提示
从零和到非零和,「解」的含义悄悄变了:零和讲最优(minimax 值是能向对手强制执行的保证),非零和只讲稳定(没人想动,但没人保证结果好)。纳什均衡存在但不唯一,也未必社会最优——囚徒困境里唯一的均衡恰恰是全局较差的结局。这也是机制设计(mechanism design)存在的理由:改造收益结构,让稳定点恰好落在想要的地方。
10. 总结
mindmap
root((博弈 II))
TD 学习
学评估函数而非手写
类比 SARSA·估 V 而非 Q
从 V 读策略需要模型
用 RL 因状态数指数级
自举·平方损失·梯度步
自我对弈 self-play
TD-Gammon 与 AlphaGo
同时博弈
游戏树失效
收益矩阵
纯策略 vs 混合策略
minimax 定理
max min 等于 min max
公开最优混合策略不吃亏
Morra 最优 7比5 分 值负十二分之一
非零和
纳什均衡存在但不唯一
囚徒困境
关键要点:
- 学评估函数:博弈的评估函数不必手工写,可以用 TD 学习从经验中学 $V_\pi(s)$——$\text{TD 学习} : V_\pi :: \text{SARSA} : Q_\pi$;更新为 $V(s) \leftarrow V(s) + \alpha\,\big[r + \gamma V(s') - V(s)\big]$。
- 从 V 读策略:博弈里转移确定,$\pi_{\text{new}}(s) = \arg\max_a V_\pi(\mathrm{Succ}(s, a))$;这一步需要知道 MDP,而博弈规则恰好完全已知。
- 为何用 RL:不是因为 MDP 未知(L8 的动机),而是因为状态数指数级,必须用函数逼近(价值网络)+ 采样经验。
- 自我对弈:双方共用一个 $V$,一方 $\arg\max$ 一方 $\arg\min$;对弈产经验、经验更新 $V$、更强的 $V$ 产生更强的对弈——TD-Gammon、AlphaGo Zero 的共同引擎,历史趋势是手工知识越来越少。
- 同时博弈:游戏树失效;纯策略下先走者劣势,但引入混合策略后 minimax 定理保证 $\max\min = \min\max$,先后手等价,公开最优混合策略也不吃亏——Morra 最优 $[\tfrac{7}{12}, \tfrac{5}{12}]$,博弈值 $-\tfrac{1}{12}$(偏向 B)。
- 纳什均衡:非零和博弈的解概念从”最优”退为”稳定“;Nash (1950) 保证有限博弈至少一个均衡,但不唯一、非社会最优(囚徒困境)。
下一讲预告:至此走完了「状态型模型」(搜索 → Lecture 7 · 马尔可夫决策过程 → 博弈)。接下来转向变量型模型——如何用图刻画随机变量之间的依赖并做概率推断?→ Lecture 12 · 贝叶斯网络 I:建模与推断。
复习自测
题目
SARSA 估计 $Q_\pi(s,a)$(动作价值),TD 学习估计 $V_\pi(s)$(状态价值)。从 Q 读策略直接 $\arg\max_a Q(s,a)$ 即可——“执行 a 之后会怎样”已经折在 Q 里。从 V 读策略必须自己往前看一步:$\arg\max_a \sum_{s'} T(s,a,s')[R + \gamma V(s')]$,需要 $T, R$。博弈里规则已知且转移确定,这一步简化为 $\arg\max_a V(\mathrm{Succ}(s,a))$,所以”只学 V”在博弈里格外划算(少一个动作维度)。
题目
A 亮 $[p, 1-p]$,B 纯应对:出 1 得 $2p - 3(1-p) = 5p-3$,出 2 得 $-3p + 4(1-p) = 4-7p$。B 取最小,A 最大化该下包络;最优在交点 $5p-3 = 4-7p \Rightarrow p = 7/12$,值 $= -1/12$。对 B 对称推导得同样的 $[7/12, 5/12]$。博弈值为负说明该游戏偏向 B——“看起来对称”的收益矩阵并不对称($+2$ 对 $+4$ 不平衡)。
题目
固定先走者的混合策略后,博弈值是后走者概率分布的线性函数,线性函数在概率单纯形上的极值必在顶点(纯动作)取到,混合不可能严格更好。作用:它把”对手的最优应对”从无穷多个混合策略压缩成有限个纯动作的枚举,使先走者的问题变成”最大化若干条直线的下包络”——两动作时可直接手算交点,一般情形正好是一个线性规划。
题目
不矛盾,二者刻画的对象不同。纯策略被公开后,对手能精确克制(Morra 里至多拿 $-3$);而公开最优混合策略 $[7/12,5/12]$ 后,由 minimax 定理 $\max\min=\min\max$,对手的最优应对也只能把你压到博弈值 $-1/12$,与不公开时相同。需要保密的是每局抽到的具体动作,不是分布本身。本质是无差异原则:最优混合让对手所有应对的收益相等,无从”针对”。
题目
零和博弈的 minimax 解提供最优性保证:无论对手做什么,你至少拿到博弈值(可强制执行的下界),且博弈值唯一。纳什均衡只提供稳定性:没人有单方面偏离的动机——不承诺结果的好坏,也不唯一。囚徒困境里唯一的均衡(双双招供,各 $-10$)严格差于双双沉默(各 $-1$):稳定点可以是集体次优的,个体理性不蕴含集体理性。
题目
因为零和:一个站在 agent 视角的 $V$ 已完整刻画双方利害,agent 取 $\arg\max V(\mathrm{Succ})$、对手取 $\arg\min V(\mathrm{Succ})$ 即可。循环之所以有效:当前 $V$ 决定双方策略 → 对弈生成带终局信号的经验 → TD 更新让 $V$ 更准 → 更准的 $V$ 给出更强的策略。同时对手强度始终与自己匹配(训练难度自动课程化),且不依赖任何人类棋谱——这是 TD-Gammon 与 AlphaGo Zero 的公共配方。
参考资料
- 💻 td_learning.py — TD 学习与自我对弈
- 💻 simultaneous_games.py — 同时博弈、minimax 定理、纳什均衡
- 📖 Sutton & Barto: Reinforcement Learning (2nd ed.) — 第 6 章:时序差分学习(TD Learning)
- 📄 Temporal Difference Learning and TD-Gammon (Tesauro, 1995) — 神经网络自我对弈的开山之作
- 📄 Some Studies in Machine Learning Using the Game of Checkers (Samuel, 1959) — 「机器学习」一词与自我对弈的起点
- 📄 Mastering the game of Go without human knowledge (AlphaGo Zero, Silver et al., 2017) — 纯自我对弈登顶
- 📄 Zur Theorie der Gesellschaftsspiele (von Neumann, 1928) — minimax 定理原始论文
- 📄 Equilibrium Points in N-Person Games (Nash, 1950) — 纳什均衡存在性定理
- 🌐 CS221 课程主页 — 课程讲义与作业