工作台课程

CS221 · 人工智能:原理与技术

Lecture 11 · 博弈 II:TD 学习与同时博弈

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}$,五步一循环:

  1. 拿到一段经验 $(s, a, r, s')$;
  2. 模型预测:$V(s; \mathbf{w})$;
  3. 构造自举目标(bootstrap target):$r + \gamma\, V(s'; \mathbf{w})$;
  4. 平方损失:$$\mathcal{L}(\mathbf{w}) = \Big(V(s; \mathbf{w}) - \big(r + \gamma\, V(s'; \mathbf{w})\big)\Big)^2$$
  5. 梯度步:$\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 · 马尔可夫决策过程不可靠电车 MDPFlakyTramMDP:走路确定 +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 的公共配方。


参考资料