🏠 总目录📚 本教程 12 · 评估函数与棋类 AI
📑 本页目录(点开跳转)

12 · 评估函数与棋类 AI

34 分钟 | ⭐ 搜索总得停下来;停下来那一刻拿什么给局面打分,决定了引擎的棋力


🎯 一句话

搜不到终局就得在半路给局面估分:评估函数是一串特征的加权和。 ⚠️ 但固定深度会带来地平线效应 —— 程序把坏消息推到搜索深度之外,然后以为它不存在。


🛑 一、Shannon 1950 的两条路

第 10 章算过国际象棋是 $35^{100} \approx 10^{154}$,第 11 章的 α-β 把它砍成 $35^{50}$ —— 还是毫无可能。 所以讲义在「关键思想」里单列一条:有限地平线 + 近似评估(Zuse 1945、Wiener 1948、Shannon 1950)。Shannon 同时给了两条路:

做法 谁在用
Type A 固定深度、全宽度搜完 深蓝,以及所有现代 α-β 引擎的骨架
Type B 只挑有希望的几步,但搜得更深 人类棋手;MCTS 的精神

⭐ 现代引擎两个都要:α-β 全宽度搜到 $d$ 层(A),再对「危险」的分支单独往下延伸(B)。


📊 二、评估函数:一串特征的加权和

$$\text{EVAL}(s) = \sum_i w_i\, f_i(s)$$

讲义给的国际象棋特征分四类:

内容
子力 后 = 9,车 = 5,马 = 象 = 3,兵 = 1
位置 某个子在某个格上的分数(小数)
交互 一个子攻击 / 保护另一个子的分数(小数)
其他 兵型、机动性……

KnightCap 用了 2000 个特征。⭐ 为什么 2000 个还能算得飞快?讲义的解释是稀疏: 任一局面下绝大多数特征都是 0(后同时只能待在 64 格里的一格)。 再加上增量更新 —— 走一步只有少数几个特征会变,没必要重算整个和。

⭐ 权重不必手调,可以用强化学习学出来(讲义原话)。这条线在强化学习基础整套 16 章里讲透了,本板块不重写。

⭐⭐ 一个容易忽略的性质:对 Minimax,只有序重要

叶子值 根选哪一支
$1, 2, 2, 4$
$1, 20, 20, 400$ 还是右

任何单调变换都不改变 Minimax 选出的走法(讲义:"move choice is preserved under any monotonic transformation of EVAL")。 确定性博弈里的收益是序数效用 —— 只要排序对,数值本身怎么缩放都无所谓。⚠️ 这条舒服的性质,下一节遇到骰子就没了。


👻 三、地平线效应

⚠️ 定义:坏事就发生在搜索深度之外那一步。 程序找到一串拖延的走法,把坏消息推到地平线以外 —— 于是它「看不见」了,评估函数还挺高兴。

一个标准场景:黑方有个象必然要被吃掉,怎么都保不住。程序搜到深度 8,发现可以先用兵去将军 —— 白方必须应,消耗掉两层;再送一个兵将军,又两层。等深度用完,象还在盘上,评估函数给了高分。 代价是白送三个兵,而象下一步照丢不误。

⭐⭐ 关键认识:这是「固定深度」本身的病,不是评估函数写得不好。 深度从 8 加到 10,只是把地平线往后挪两层,程序会多送两个兵。

治法:静默搜索

静默搜索(quiescence search):到达深度上限时先看一眼局面安不安静 —— 有没有吃子、将军、后被攻击? 不安静就继续往下搜,但只搜这些强制性走法,直到平静了再评估。 讲义原话:「如果存在危险局势(例如后正被攻击),就延伸搜索深度。」

⭐ 直觉:评估函数只在静态局面上可信。 兑子兑到一半的时候给盘面打分是没有意义的 —— 你数的子力,下一步就要变。

讲义说现代象棋程序依赖三样东西:静默搜索、置换表、剪枝启发式 —— 后两样都在第 11 章


🎲 四、期望极小极大:骰子进来了

西洋双陆棋、大富翁这类博弈里,树上多一层 CHANCE 节点(掷骰子、洗牌、发牌)。 讲义的改法只有一行:CHANCE 节点返回子节点值的平均(按概率加权)。

$$V(\text{chance}) = \sum_k P(k)\, V(\text{子}_k)$$

CHANCE 层取的是期望 —— 不是最大也不是最小MAXCHANCE叶子5540.50.50.50.510044左:0.5×10 + 0.5×0 = 5  右:0.5×4 + 0.5×4 = 4  根选左
一棵最小的期望极小极大树。两支的期望是 5 和 4,MAX 选左。下面会看到:把评估函数做一次单调变换,这个选择会翻过来。

⭐⭐ 现在精确值要紧了

拿上图做实验。把评估函数换成 $\sqrt{\cdot}$ —— 它是严格单调递增的,按第二节的说法不该影响任何东西:

原来 换成 $\sqrt{\cdot}$ 之后
左支 $0.5 \times 10 + 0.5 \times 0 = \mathbf{5}$ $0.5\sqrt{10} + 0.5 \times 0 \approx \mathbf{1.58}$
右支 $0.5 \times 4 + 0.5 \times 4 = \mathbf{4}$ $0.5 \times 2 + 0.5 \times 2 = \mathbf{2.00}$
MAX 选 ⚠️

同一棵树,同一个单调变换,走法翻了。

⭐⭐ 确定性博弈里 EVAL 是序数的(排序对就行); 随机博弈里 EVAL 必须是基数的 —— 讲义的原话是 EVAL 应当正比于期望收益

这就是为什么 TD-Gammon 的网络输出被明确解释成获胜概率,而不是随便一个「越大越好」的分数。

⚠️ 代价:骰子把分支因子乘上去了。双陆棋每回合有 21 种骰子结果,复杂度变成 $O\big((bn)^m\big)$,实际只能搜 2–3 层。 α-β 也能改编到随机博弈上,但讲义说了前提:评估必须有界


🕹 五、棋类 AI 简史

事件
1769 / 1846 土耳其行棋傀儡(骗局);Babbage 与 Lovelace 的井字棋机器
1912 / 1944 Zermelo、von Neumann:完美对弈的算法存在
1950 / 1951 Shannon:有限地平线 + 近似评估;Turing:第一个国际象棋程序
1956 / 1959 McCarthy:剪枝;Samuel 跳棋:⭐ 哈希表、数据压缩、用机器学习调参数三首创
1961 Michie 的 MENACE(用火柴盒学井字棋)
1989–95 / 1997 TD-Gammon深蓝击败卡斯帕罗夫
2007 / 2016 / 2017 Chinook 证明跳棋必和;AlphaGo;AlphaZero

三条值得单独记:

深蓝(1997) 六局击败卡斯帕罗夫。传统上电脑开局强(开局库)、残局强(深搜), 人类靠中局「打开局面」抬高分支因子取胜 —— 卡斯帕罗夫试了,但深蓝速度够快扛住了。 ⚠️ 现在普通 PC 上的引擎已经明显强于深蓝。

Chinook 的残局库覆盖 8 子以下的全部 443,748,401,247 个局面(后扩到 10 子、38 万亿)。 2007 年 Schaeffer 证明跳棋双方最优下必和,方法是增量地把博弈树填出来、跳过那些大概率会被剪掉的分支, 算了几个月后收敛到「真实的(剪枝后的)树」的骨架 —— ⭐ 第 11 章的剪枝在这里直接变成了证明工具

TD-Gammon(Tesauro):196 个输入、20 个隐藏单元、1 个输出,输出就是获胜概率。 Tesauro 训了两个网络对比 —— EP 网(学人类专家偏好,监督学习)和 TD 网(自我对弈,TD 学习),TD 网赢了。 再加上三步前瞻(期望极小极大)和手工特征,1995 年成为世界最强双陆棋手。

⭐ 讲义解释了它为什么在双陆棋上行得通:骰子的随机性逼着自我对弈去探索大得多的搜索空间。 而在国际象棋这种确定性博弈上,直接 TD 学习效果很差 —— 必须把学习和树搜索结合起来。

TreeStrap(Veness 2009)就是那个结合:非叶节点也一起更新(包括没被选中的走法), 而且 ⭐⭐ α-β 造成截断时那个上界或下界照样能拿来当训练目标 —— 正是第 11 章说的「被剪节点的值退化成一个界」。 它第一次证明国际象棋可以从随机初始权重、纯自我对弈练到大师级。


🌲 六、MCTS 和 α-β 的分工

围棋分支因子超过 300,而且静态评估极难写(一块棋是死是活往往要算到很深才知道),α-β 那条路走不动。 MCTS 换了思路:不穷举,采样 —— 树随机地一点点长出来,走一小段之后把剩下的棋随机下完,用大量对局的胜率统计代替评估函数。

⭐ 分工一句话: α-β = 穷举 + 剪枝 + 一个写得出来的评估函数;MCTS = 采样 + 统计,不需要评估函数。 分支小、评估写得出来的地方(国际象棋)α-β 至今仍最强;分支 300 以上、评估难写的地方(围棋)MCTS 赢。

AlphaGo 是 MCTS + 深度网络(先学人类棋谱再自我对弈),AlphaZero 完全靠自我对弈。

⭐⭐ 最后一个扣子:自我对弈为什么讲得通? 因为围棋、象棋、将棋都是二人零和博弈 —— 第 13 章证明了这类博弈的值 $v$ 唯一、且「最优策略」与对手打什么无关, 两边都在逼近同一个确定的东西。⚠️ 换成非零和(谈判、多方拍卖),「自我对弈会收敛到什么」重新变成没有答案的问题。


🔗 这一章连到哪里

去哪 为什么
11-剪枝.html 剪枝让你搜得更深,本章讲搜到头之后怎么办;⭐ TreeStrap 正好拿「被剪节点退化成的界」当训练目标
../博弈论与集体决策/13-零和与极大极小.html ⭐⭐ 那一章讲清了自我对弈为什么讲得通 —— 底下垫的是零和的极大极小定理
../强化学习基础/05-蒙特卡洛与时序差分.html TD-Gammon 用的 TD 学习本体在那里;本章只讲它怎么用,不重写学习算法
../强化学习基础/index.html 「评估函数的权重可以用强化学习学出来」的完整展开,是那边整套 16 章
13-CSP是什么.html 下一站换个问法:不问「怎么走到目标」,而问「哪一组赋值同时满足所有约束」—— 路径不重要了

✅ 检查点

  1. Shannon 1950 给的 Type A 和 Type B 各是什么?现代引擎用哪个?
  2. 评估函数长什么样?KnightCap 有 2000 个特征,为什么还算得飞快?对 Minimax,它的精确值要紧吗?
  3. 什么是地平线效应?举一个具体场景。为什么说「加深一层」治不好它?
  4. 静默搜索怎么做?背后的直觉是什么?
  5. 手算:左 CHANCE 节点两个等概率叶子是 10 和 0,右边是 4 和 4。MAX 选哪支?把评估函数换成 $\sqrt{\cdot}$ 之后呢?这说明了什么?
  6. Chinook 的残局库覆盖了多少个局面?Schaeffer 证明跳棋必和用的是什么方法?
  7. TD-Gammon 为什么在双陆棋上成功,而直接 TD 学习在国际象棋上不行?
  8. α-β 和 MCTS 的分工是什么?自我对弈能收敛,底下垫的是哪条结论?
👀 答案
  1. Type A = 固定深度、全宽度搜完;Type B = 只挑有希望的几步但搜得更深。⭐ 现代引擎两个都用:α-β 全宽度搜到 $d$ 层,再对危险分支单独延伸。
  2. $\text{EVAL}(s) = \sum_i w_i f_i(s)$,特征分子力(后 9 / 车 5 / 马 = 象 3 / 兵 1)、位置、交互、兵型机动性。算得快是因为稀疏 —— 任一局面下绝大多数特征是 0(后同时只能在一格),再加增量更新。⭐ 精确值不要紧,只有序重要:$1,2,2,4$ 和 $1,20,20,400$ 选出同一支,任何单调变换都不改变 Minimax 的走法,确定性博弈里收益是序数效用
  3. 坏事就在搜索深度之外那一步,程序用一串拖延走法把它推到地平线外。场景:黑象必丢,程序先送兵将军消耗层数,深度用完时象还在盘上、评估函数给高分,代价是白送三个兵而象照丢。⭐⭐ 治不好是因为这是固定深度本身的病 —— 加深两层只是把地平线挪两层。
  4. 到深度上限时先看局面安不安静(吃子、将军、后被攻击);不安静就继续往下搜,但只搜这些强制走法,直到平静再评估。⭐ 直觉:评估函数只在静态局面上可信
  5. 原来左 $=5$、右 $=4$,选左;换 $\sqrt{\cdot}$ 后左 $=0.5\sqrt{10}\approx1.58$、右 $=2.00$,⚠️ 选右。⭐⭐ 随机博弈里单调变换会翻转走法,所以 EVAL 必须正比于期望收益,不能只保证序。
  6. 443,748,401,247 个(8 子以下全部,后扩到 10 子、38 万亿)。方法是增量填博弈树、跳过大概率会被剪掉的分支,几个月后收敛到「真实剪枝树」的骨架 —— ⭐ 剪枝变成了证明工具。
  7. ⭐ 因为骰子的随机性逼着自我对弈探索大得多的搜索空间。确定性博弈里直接 TD 学习效果很差,必须把学习和树搜索结合 —— TD-Leaf、TreeStrap(后者连 α-β 截断产生的上下界都拿来当训练目标)。
  8. α-β = 穷举 + 剪枝 + 一个写得出来的评估函数;MCTS = 采样 + 统计,不需要评估函数。 象棋归前者,围棋(分支 300+、评估难写)归后者。自我对弈能收敛,垫在底下的是零和的极大极小定理:值 $v$ 唯一、最优策略与对手无关。⚠️ 非零和没这个保证。

🛑 可以停在这里

走神救援

α-β 把象棋从 $35^{100}$ 砍到 $35^{50}$,还是搜不完,所以必须半路停下来估分 —— 这就是 Shannon 1950 的「有限地平线 + 近似评估」。他给了两条路:Type A(固定深度、全宽度)和 Type B(只挑有希望的几步、搜得更深),现代引擎两个都用。评估函数是特征加权和 $\sum w_i f_i(s)$:子力(后 9 / 车 5 / 马 = 象 3 / 兵 1)、位置、交互、兵型机动性。KnightCap 有 2000 个特征却算得飞快,因为任一局面下绝大多数特征是 0(稀疏)+增量更新。⭐⭐ 对 Minimax,精确值不要紧、只有序要紧 —— $1,2,2,4$ 和 $1,20,20,400$ 选出同一支,收益是序数效用。⚠️ 地平线效应:坏事就在深度之外那一步,程序用一串拖延走法把它推出去 —— 黑象必丢,它先送兵将军消耗层数,深度用完时象还在盘上、评估函数给高分,代价是白送三个兵而象照丢。⭐⭐ 这是固定深度本身的病,加深两层只是把地平线挪两层。治法是静默搜索:到深度上限先看局面安不安静(吃子、将军、后被攻击),不安静就只沿强制走法继续搜,直到平静再评估。⭐ 直觉:评估函数只在静态局面上可信期望极小极大给树加一层 CHANCE 节点,值取子节点的概率加权平均。⭐⭐ 这里精确值突然要紧了:左支 $0.5\times10+0.5\times0=5$、右支 $4$,选左;把 EVAL 换成 $\sqrt{\cdot}$(严格单调递增!)后变成 $1.58$ 对 $2.00$,走法翻了。所以随机博弈里 EVAL 必须正比于期望收益 —— 这正是 TD-Gammon 输出被解释成「获胜概率」的原因。双陆棋每回合 21 种骰子结果,实际只搜 2–3 层。简史里三条:1997 深蓝(卡斯帕罗夫想靠打开局面抬高分支因子,被速度扛住);2007 Chinook443,748,401,247 个 8 子残局 + 「增量填树、跳过会被剪的分支」证明跳棋必和(⭐ 剪枝变成了证明工具);TD-Gammon(196 输入 / 20 隐层 / 1 输出=获胜概率,TD 自我对弈网打赢了监督学专家偏好的网)。⭐ 它在双陆棋行得通是因为骰子逼着自我对弈探索大得多的空间;确定性博弈得靠 TreeStrap(连 α-β 截断产生的上下界都拿来训练,正是 11 章那个「值退化成界」)。最后 α-β 与 MCTS 的分工:前者穷举 + 剪枝 + 写得出来的评估函数,后者采样 + 统计、不需要评估函数;象棋归前者,围棋归后者。⭐⭐ 自我对弈之所以讲得通,垫在底下的是零和的极大极小定理:值唯一、最优策略与对手无关。非零和就没这个保证。

下一节 👉 13-CSP是什么.html

打卡记录保存在你的浏览器里,首页能看到总进度