人工智能导论:非神经网络部分期末学习指南
这份 HTML 面向“从零开始复习”的状态,覆盖课件1搜索、课件6对抗搜索、课件7蒙特卡罗、课件8强化学习/AlphaGo、决策树补充笔记,并把 2021、2024 与往年常见题型整理成可直接套用的解题步骤。本版按 2024 真题补强了第1、2、5、6题相关内容,并按你的要求跳过第3题 SVM 与第4题 GoogleNet/Inception。
搜索与A*α-β剪枝MCTS强化学习ID3 / C4.5模拟退火与遗传算法2024真题增补0. 怎么用这份指南
如果你之前完全没听课,最重要的不是先背概念,而是先把“考试会让你做什么”看清楚。2021 与2024真题的共同重点非常清楚:α-β剪枝、修正A*、ID3/C4.5决策树,以及围棋策略网络/MCTS训练思路。课件里还覆盖 MCTS、AlphaGo、AlphaGo Zero、Viterbi、模拟退火、遗传算法等知识点,其中有些更偏理解题或选择题。
第一遍:建立地图
先看每节开头的“本节你要会什么”和图示,不纠结公式推导,只要知道算法在干什么、输入输出是什么。
第二遍:照模板算题
重点练 A*/修正A*、α-β、ID3/C4.5、模拟退火、遗传算法。每种题都能被拆成固定表格或固定流程。
第三遍:抓坑点
考场最容易错的是 A* 何时结束、α-β跟哪个祖先比较 的 b 怎么求、软间隔 α/ξ 怎么对应图上位置。
1. 期末题型地图:你最终要能做什么
| 题型 | 2021/往年表现 | 你要交出的东西 | 核心套路 |
|---|---|---|---|
| α-β剪枝 | 2021第1题;往年几乎反复出现 | 每个内部节点值、剪枝位置、最终走步 | 叶子向上算 minimax;从左到右维护 α/β;一旦 α≥β 剪剩余兄弟;根节点选最大值分支。 |
| 修正A* | 2021第2题;2013问 fm 的目的和理由 | OPEN/CLOSED过程、扩展顺序、最终路径 | 维护 fm;若 OPEN 中存在 f<fm 的节点,选其中 g 最小者;否则选 OPEN 的最小 f 并更新 fm。 |
| 模拟退火 | 2021第4题之一;旧题有固定温度表格 | 每一步是否接受、接受概率或接受率 | 更优必接受;更差按 exp(-ΔE/T) 与随机数比较;拒绝后当前状态不变。 |
| 遗传算法 | 2021第4题之一;旧题考轮盘赌/确定性选择 | 选择出的个体、概率、可能的交叉/变异过程 | 适应值归一化成概率;累积区间对随机数;确定性选择按期望复制数。 |
| ID3/C4.5决策树 | 2021第5题,根节点及子节点 | 信息熵、信息增益、增益率、根节点选择、递归终止条件 | 算 \(H(D)\),对每个特征算 \(H(D\mid A)\) 与 \(g(D,A)\),ID3选信息增益最大特征;C4.5用信息增益比修正偏好。 |
| softmax策略网络训练 | 2024第6题:无隐层策略网络 + MCTS访问次数 | 写出 net、softmax、损失函数、梯度和权重更新 | 把 MCTS 选择次数归一化成目标分布 \(q_j=m_j/\sum_k m_k\),用交叉熵 \(-\sum_j q_j\log p_j\),梯度为 \((p_j-q_j)x_i\)。 |
| MCTS/AlphaGo/强化学习 | 2021提示近年范式含MCTS;课件6-8覆盖 | 通常为概念、流程、走步选择或简算 | MCTS四步:选择、扩展、模拟、回传;UCT平衡探索和利用;AlphaGo把策略/估值网络接入MCTS。 |
1.1 2024真题增补:本版新增了哪些东西
| 2024题号 | 对应章节 | 新增训练重点 | 考场得分点 |
|---|---|---|---|
| 一 | 3.7 | 不齐树、终局值与中间扩展节点混在一起时,仍然严格按层的 MAX/MIN 倒推。 | 每个生成节点写倒推值;剪枝处写 \(\alpha\ge\beta\) 或 \(\beta\le\alpha\);最后写根节点走哪条边。 |
| 二 | 2.3.4 | 修正A*中同一节点可能多次被更优路径重新打开,扩展序列不等同于“每个点只出现一次”。 | 列出 \(f_m\)、NEST、OPEN、父指针;最终路径为 S-D-C-B-A-T,代价 22。 |
| 五 | 6.10 | 信息增益和信息增益比都要算;数据表很小但很容易把条件熵权重漏掉。 | \(H(D)=1\);A 的信息增益约 0.082,B 为 0;ID3 与 C4.5 第一步都选 A。 |
| 六 | 5.7 | 把 MCTS 访问次数 \(m_j\) 转为训练目标分布 \(q_j\),再推 softmax + 交叉熵梯度。 | 写出 \(net_j\)、\(p_j\)、\(L\)、\(\partial L/\partial w_{ji}\) 与更新式。 |
2. 搜索问题总览
搜索问题的本质:在一个巨大的状态空间里,从初始状态 S₀ 找到目标状态 Sg,最好还能找到代价最小的解路径。课件1从导航、机器证明、大模型解码引入搜索,强调关键问题是“如何利用知识,尽可能有效地找到解或最佳解”。
2.0.1 搜索算法的共同语言
| 符号 | 含义 | 考场用法 |
|---|---|---|
| OPEN | 待扩展节点表 | 每一步从 OPEN 中按规则取一个节点扩展;A/A*通常按 f 从小到大排序。 |
| CLOSED | 已扩展节点表 | 防止重复扩展;但一般A算法中若发现 CLOSED 节点更优路径,可能要重新放回 OPEN。 |
| g(n) | 从起点到 n 的已知路径代价估计 | 沿父指针累加边权;Dijkstra只看 g。 |
| h(n) | 从 n 到目标的启发式估计 | A/A*根据它少走弯路;题目通常给出 h 或让你设计 h。 |
| f(n)=g(n)+h(n) | 经过 n 到目标的总代价估计 | A/A*从 OPEN 中选 f 最小的点。 |
| 父指针 | 记录一个节点从哪个节点来 | 到达目标后,从目标沿父指针倒推得到解路径。 |
2.1 深度优先、宽度优先、Dijkstra
2.1.1 深度优先搜索 DFS
深度优先搜索优先扩展深度更深的节点,像“沿着一条路走到底,不行再退回来”。课件用八皇后展示了它的状态空间:每放一个皇后,状态就多一行皇后位置;若冲突则回溯。
性质
- 找到的第一个解不保证最优。
- 深度限制不合理时可能找不到解。
- 最坏情况等同穷举。
- 优点是节省内存,只需存当前路径和少量备选。
适用
- 解很深但分支不太多,或者只要任意解。
- 约束满足问题,如八皇后、数独,常配合回溯。
- 不适合求最短路,除非额外剪枝或迭代加深。
2.1.2 宽度优先搜索 BFS
宽度优先搜索优先扩展深度浅的节点,像“先看一步能到哪里,再看两步能到哪里”。
2.1.3 Dijkstra算法
Dijkstra 弥补 BFS 不看边权的问题:每次优先扩展当前离起点最近的节点,也就是 g(n) 最小的节点。它不使用目标方向信息,因此能保证最短路,但可能在目标反方向也扩展很多节点。
2.2 A算法、A*算法、启发函数与单调性
2.2.1 A算法
A算法引入启发知识,用 f(n)=g(n)+h(n) 对 OPEN 中的节点排序。g(n) 表示已经走了多远,h(n) 猜还要走多远。每次扩展 f 最小的节点。
OPEN = {s}, CLOSED = {}
while OPEN 非空:
n = OPEN 中 f 最小的节点
if n 是目标: 返回路径
从 OPEN 删除 n,加入 CLOSED
扩展 n 的后继 m
计算经 n 到 m 的新 g 和 f = g + h
如果 m 新发现: 加入 OPEN,父指针指向 n
如果 m 已在 OPEN 且新 f 更小: 更新 f 和父指针
如果 m 已在 CLOSED 且新 f 更小: 重新放回 OPEN,更新父指针
2.2.2 A*算法:可采纳的A算法
如果启发函数满足 h(n) ≤ h*(n),其中 h*(n) 是 n 到目标的真实最短代价,那么这个 A 算法叫 A*。直观理解:启发函数要“乐观”,可以低估剩余距离,但不能高估。
可采纳性定理
若从初始节点到目标存在路径,A* 必能找到最佳解。
启发函数设计原则
放宽原问题限制,在更容易的问题上求一个下界。8数码中“不在位块数”和“曼哈顿距离和”都是典型例子。
2.2.3 8数码的两个典型 h
| 启发函数 | 定义 | 为什么可采纳 | 强弱 |
|---|---|---|---|
| h₁(n) | 不在目标位置的牌数 | 每次移动最多让一个牌归位,因此真实剩余步数至少是不在位牌数的某种下界。 | 较弱,扩展节点较多。 |
| h₂(n) | 所有牌到目标位置的曼哈顿距离和 | 每移动一步只让某个牌的曼哈顿距离改变1,因此真实步数至少为距离和。 | 较强,通常扩展节点更少。 |
2.2.4 启发信息越多,扩展节点越少?
课件给出定理:同一问题上两个A*算法 A₁、A₂,若对所有非目标节点都有 h₂(n)>h₁(n),则 A₁ 扩展的节点数至少与 A₂ 一样多。注意这里是严格大于,且评价指标是“扩展过的不同节点数”,同一节点重复扩展多次只算一次。
2.2.5 单调性:让A*不必反复重开节点
启发函数 h 如果对每条边 nᵢ→nⱼ 都满足:
就叫单调启发函数,也叫一致启发函数。它的含义类似三角不等式:从 nᵢ 到目标的估计,不应大于“先走到 nⱼ 的代价 + 从 nⱼ 到目标的估计”。
2.2.6 A*考场流程
- 先在图上标出每个节点的 h 和每条边代价。
- 建立表格:步骤、扩展节点、g、h、f、OPEN、CLOSED、父指针。
- 每扩展一个节点,计算后继的 g_new=g(parent)+cost,再算 f_new=g_new+h。
- 如果后继已出现,比较新旧 g 或 f;若新路径更优,更新父指针。
- 只在目标成为下一次扩展节点时停止。
- 从目标沿父指针回溯到起点,写出路径和总代价。
2.2.7 一个可手算的A*小例子
假设图如下:S 到 A 代价2,S 到 B 代价5;A 到 C 代价2,B 到 C 代价1;C 到 G 代价3,A 到 G 代价8。启发函数为 h(S)=5,h(A)=4,h(B)=3,h(C)=2,h(G)=0。
| 步 | 扩展 | 新生成/更新 | OPEN(按f排序) | CLOSED |
|---|---|---|---|---|
| 0 | 无 | S: g=0, f=5 | S(0+5=5) | 空 |
| 1 | S | A: g=2,f=6;B:g=5,f=8 | A(6), B(8) | S |
| 2 | A | C:g=4,f=6;G:g=10,f=10 | C(6), B(8), G(10) | S,A |
| 3 | C | G 经C更新为 g=7,f=7 | G(7), B(8) | S,A,C |
| 4 | G | 目标被选中,结束 | B(8) | S,A,C,G |
解路径由父指针回溯为 S→A→C→G,总代价7。注意第2步生成 G 时不能立刻停,因为当时 OPEN 中有 C 的 f=6 小于 G 的 f=10。
2.2.8 启发函数设计与评价
课件用“传教士与野人”说明启发函数设计:放宽安全约束,只保留船容量约束,估计至少还需摆渡多少次。这样得到的是宽松问题下的最少次数,因此不会高估真实问题的剩余代价,满足A*条件。课件中还给出一种状态表示下的估计 h=M+C-2B,其中 M、C 是左岸剩余人数,B 表示船是否在左岸。
启发函数的效果可用平均分叉数 b* 评价。若解深度为 d、总搜索节点数为 N,则近似满足:
b* 越小,说明启发函数越有效。课件的8数码实验中,曼哈顿距离和通常比“不在位牌数”有更小的平均分叉数。
2.3 修正的A*算法:fm 与 NEST
修正A*是2021明确出现的题型。它的目标是:在保持可采纳性的前提下,减少普通A*由于重新打开 CLOSED 节点造成的重复扩展,而且不比普通A*扩展更多节点。
2.3.1 为什么要改
普通 A 算法中,如果某个已经扩展过的节点后来发现更短路径,就要把它重新放回 OPEN,这会导致重复扩展。课件提出两个途径:一是限制 h,使它单调;二是改算法,用 fm 和 NEST 控制扩展顺序。
NEST 不为空时,为什么选 g 最小的节点?
答:g
最小意味着该节点在搜索树中最靠近起点(处于上游)。这样做是为了“先把靠近起点的基础夯实,把真实的代价确定下来”,再去探索深处的节点。这样就能极大程度上避免“深层的节点被扩展完后,因为浅层节点找到更优路径而被迫重算”。
2.3.2 修正A*规则
Modified-A*(s):
OPEN = {s}; CLOSED = {}; f(s)=g(s)+h(s); fm=0
while OPEN 非空:
NEST = { n in OPEN | f(n) < fm }
if NEST 非空:
n = NEST 中 g 最小的节点
else:
n = OPEN 中 f 最小的节点
fm = f(n)
if n 是目标: 返回路径
扩展 n,更新 OPEN/CLOSED/父指针
2.3.3 这道题怎么写才稳
2.3.4 2024真题同型例题:修正A*完整表
2024第2题给的是一个有向图,弧线边数字为代价,启发值为:\(h(S)=14,h(E)=8,h(A)=1,h(B)=4,h(C)=8,h(D)=14,h(T)=0\)。可读出的关键有向边如下:
| 步 | 选出/扩展节点 | 选择理由 | 主要生成或更新 |
|---|---|---|---|
| 0 | S | OPEN 只有 S,置 \(f_m=14\) | E(15,23), A(11,12), B(9,13), C(6,14), D(1,15) |
| 1 | B | NEST={A,B},取其中 \(g\) 最小的 B | A 由 g=11 改为 g=10,父指针 B |
| 2 | A | NEST={A} | 生成 T: g=28, f=28 |
| 3 | C | NEST 为空,OPEN 中最小 \(f=14\) | 重新打开 A(g=9,f=10), B(g=7,f=11) |
| 4 | B | NEST={A,B},取 \(g\) 更小的 B | A 更新为 g=8, f=9 |
| 5 | A | NEST={A} | T 更新为 g=26 |
| 6 | D | NEST 为空,OPEN 中最小 \(f=15\),置 \(f_m=15\) | A(g=7,f=8), B(g=5,f=9), C(g=2,f=10) 全部被重新打开 |
| 7 | C | NEST={A,B,C},取 \(g\) 最小的 C | B 更新为 g=3, f=7;A 更新为 g=5, f=6 |
| 8 | B | NEST={A,B},取 \(g\) 更小的 B | A 更新为 g=4, f=5 |
| 9 | A | NEST={A} | T 更新为 g=22, f=22 |
| 10 | T | NEST 为空,目标被选出 | 停止,沿父指针回溯路径 |
因此扩展/选出顺序可写为 S, B, A, C, B, A, D, C, B, A, T;若只写“真正展开后继”的节点,则最后的 T 可单独说明为“目标被选出,停止”。最终路径为:
2.4 动态规划、Viterbi 与拼音输入法
课件1后半部分把搜索用于拼音输入法。一个拼音串可能对应海量汉字序列,例如每个音平均10个候选,11个音就有约 10¹¹ 个句子,穷举不可行。
2.4.1 从概率到最短路径
输入拼音 O,候选汉字句子 S=w₁…wₙ。目标是找最大后验概率的句子:
如果简化地忽略多音字,P(O|S) 近似常量,问题变成最大化语言模型概率 P(S)。二元语法下:
于是每个候选字是图中的节点,相邻拼音位置之间的边权是 -log P(wᵢ|wᵢ₋₁),找最小代价路径就是找最可能句子。
2.4.2 Viterbi动态规划
这就是有限宽度分层图上的最短路径。若每一层只保留前 K 个候选,就变成 beam search。
2.4.3 平滑与识别后处理
二元概率常用最大似然估计:
若语料中没见过某个搭配,概率可能为0,所以要平滑。课件给出一种线性插值形式:
汉字识别后处理也类似:每个位置有多个识别候选及识别信度,用语言模型概率和识别信度共同决定最优汉字序列。
2.5 局部搜索、模拟退火、遗传算法
课件1提到爬山法、随机搜索;2021和旧题明确考模拟退火与遗传算法。它们都属于“不系统展开整棵搜索树,而是在候选解空间中移动”的方法。
2.5.1 爬山法与局部最优
爬山法每次选择邻域中更优的状态,优点是简单,缺点是容易卡在局部最优或平台。模拟退火就是为了解决“偶尔需要走差一步才能跳出坑”的问题。
2.5.2 模拟退火 SA
如果目标是最小化能量 E,从当前状态到候选状态的能量变化为 ΔE=E_new-E_current:
温度 T 高
差解也有较大概率被接受,探索更强,容易跳出局部最优。
温度 T 低
更像贪心爬山,差解很难被接受,收敛更稳定但更容易被困住。
模拟退火小例子
当前能量50,候选能量40,ΔE=-10,必接受。当前变为40。下一候选能量43,ΔE=3。温度 T=20 时 p=exp(-3/20)≈0.861。若随机数0.90,则拒绝,当前仍为40。再下一候选能量42时,ΔE=2,不是 42-43=-1。
2.5.3 遗传算法 GA
遗传算法把候选解看作个体,多个个体组成种群。基本流程是:编码、初始化种群、计算适应值、选择、交叉、变异、形成新一代。
轮盘赌选择
若种群 A、B、C、D 适应值分别为 4、6、2、8,总适应值20,则选择概率和累积区间为:
| 个体 | 适应值 | 概率 | 累积区间 |
|---|---|---|---|
| A | 4 | 0.20 | [0,0.20) |
| B | 6 | 0.30 | [0.20,0.50) |
| C | 2 | 0.10 | [0.50,0.60) |
| D | 8 | 0.40 | [0.60,1.00] |
随机数 0.15、0.55、0.25、0.45 对应选择 A、C、B、B。
确定性选择
一种常见做法是计算期望复制数 N·fitness_i / Σfitness,先取整数部分,再按小数部分从大到小补足种群规模。例如上例种群大小4,期望复制数 A=0.8、B=1.2、C=0.4、D=1.6,整数部分给 B、D 各1个,还差2个,按小数部分 A=0.8、D=0.6 最大,补 A 和 D,因此新种群可为 A、B、D、D。不同课件若指定了确定性采样方式,以题目给定规则为准。
3. 对抗搜索与 \(\alpha\)-\(\beta\) 剪枝
对抗搜索处理的是“我走一步、对手走一步”的博弈。课件里的典型前提是:双人、轮流行动、信息完备、零和。零和的意思是:一个局面对我越好,对对手就越坏,所以一棵博弈树可以只用一个效用值来描述。
3.1 先把博弈树看懂:状态、行动、效用
节点
一个节点就是一个局面。例如棋盘上已经下了若干步后的状态。
边
一条边就是一个合法行动。例如某个可落子点或一步棋。
叶子值
终局时是胜负收益;非终局但搜索深度到达上限时,用估值函数近似。
如果轮到我方行动,这一层叫 MAX 层,因为我会选择让局面对我最好的孩子;如果轮到对手行动,这一层叫 MIN 层,因为对手会选择让我最难受的孩子。于是博弈树的值递归定义为:
3.2 Minimax 手算模板:先叶子、后内部、最后根
- 先标层:根节点是 MAX 还是 MIN,下一层交替。
- 把所有叶子估值写清楚;如果题目只给叶子值,不要自己改。
- 从倒数第二层开始往上算:MAX 取最大,MIN 取最小。
- 根节点的孩子中,哪个给出根值,哪个就是当前应选择的走法。
3.3 为什么需要 \(\alpha\)-\(\beta\) 剪枝
Minimax 的问题是爆炸式增长。若每个局面平均有 \(b\) 个合法行动,向前看 \(d\) 层,叶节点数量约为 \(b^d\)。围棋、象棋一类游戏不可能完整搜完,于是我们希望:不改变 minimax 结果,但少看一些分支。
\(\alpha\)-\(\beta\) 剪枝的核心判断是:有些分支即使继续算完,也不可能改变祖先节点已经能做出的选择,因此可以提前不看。
3.4 \(\alpha\) 和 \(\beta\) 到底是什么
\(\alpha\):MAX 的下界
在某个搜索路径上,MAX 祖先已经找到的最好保证值。也就是“我至少能拿到这么多”。
\(\beta\):MIN 的上界
在某个搜索路径上,MIN 祖先已经找到的最好压制值。也就是“对手至多愿意让我拿到这么多”。
更贴近笔记的说法是:极大节点维护下界 \(\alpha\),极小节点维护上界 \(\beta\);后辈节点的 \(\beta\) 值不超过祖先的 \(\alpha\) 值时可剪,后辈节点的 \(\alpha\) 值不小于祖先的 \(\beta\) 值时也可剪。注意比较对象可以是祖先,不只是父节点。
3.5 从左到右剪枝例题
设根为 MAX,按从左到右访问叶子。左子树是 MIN,叶值为 \(3,5\);右子树是 MIN,叶值为 \(2,9\)。
| 步骤 | 看到的值 | 当前结论 | 能否剪枝 |
|---|---|---|---|
| 1 | 左 MIN 看到 3 和 5 | 左 MIN 值为 \(\min(3,5)=3\),根 MAX 的 \(\alpha=3\) | 不能,左子树已算完 |
| 2 | 右 MIN 先看到 2 | 右 MIN 的当前 \(\beta=2\) | 因为 \(\beta=2\le \alpha=3\),右 MIN 剩余孩子无需再看 |
| 3 | 右叶子 9 被剪 | 右子树最终值至多为 2,不可能超过左子树的 3 | 剪枝不改变根的选择 |
3.6 考场最容易错的四件事
只跟父节点比较
错。\(\alpha\) 和 \(\beta\) 是沿路径继承的边界,可能来自更高的祖先。
剪枝后还给被剪节点赋值
错。被剪分支没有访问,不能假装知道它的 minimax 值;图上画叉即可。
以为剪枝改变答案
错。\(\alpha\)-\(\beta\) 只减少计算,不改变完整 minimax 的最终选择。
忽略访问顺序
错。题目默认从左到右时必须按左到右;换顺序可能剪枝数量不同。
3.7 2024真题补强:不齐博弈树怎么做
2024第1题的树有一个重要变化:有些“看起来像叶子”的方框下面还接着一层后继,说明它不是终局叶节点,而是一个需要继续倒推的生成节点。做这种题时,不要按外观把所有底层方框都当成叶子;只要某个节点还有孩子,就必须继续按 MAX/MIN 规则向下算。
| 场景 | 你该怎么写 | 为什么 |
|---|---|---|
| MAX 节点看到一个孩子值为 6 | 当前 \(\alpha\leftarrow\max(\alpha,6)\) | MAX 至少可以保证 6。 |
| MIN 节点看到一个孩子值为 -2 | 当前 \(\beta\leftarrow\min(\beta,-2)\) | MIN 至多会让 MAX 得到 -2。 |
| 在 MIN 节点已有 \(\beta\le\alpha\) | 剪去该 MIN 节点剩余未访问孩子 | MAX 的祖先已经有更好选择,这个分支不可能被选。 |
| 在 MAX 节点已有 \(\alpha\ge\beta\) | 剪去该 MAX 节点剩余未访问孩子 | MIN 的祖先已经能把结果压得更低,这个分支也不可能改变决策。 |
练习:一个与2024相似的不齐树小例子
根为 MAX,有两个 MIN 子树。左 MIN 的两个孩子值分别为 4、7,所以左 MIN 值为 4,根当前 \(\alpha=4\)。右 MIN 的第一个孩子是一个 MAX 子树,其两个叶值为 1、3,所以该 MAX 值为 3。于是右 MIN 当前 \(\beta=3\)。因为 \(\beta=3\le\alpha=4\),右 MIN 的剩余孩子全部剪去。根最终选择左分支,值为 4。
4. 蒙特卡洛方法与蒙特卡洛树搜索 MCTS
蒙特卡洛方法的思想很朴素:如果一个量精确算不出来,就随机试很多次,用平均结果估计它。在博弈里,一个落子点到底好不好,可能难以用公式直接判断,于是可以从这个落子点开始随机模拟很多盘,看最后赢的比例。
4.1 从“随机试很多次”到期望估计
设随机变量 \(X\) 表示一次模拟的收益,例如赢为 \(1\),输为 \(0\),或者赢为 \(1\)、输为 \(-1\)。真实期望 \(\mathbb E[X]\) 不容易直接求,但可以做 \(N\) 次独立模拟:
模拟次数越多,样本平均通常越接近真实期望。放到棋局里,如果某个行动经过 100 次随机模拟赢了 63 次,就可以暂时估计它的胜率为 \(0.63\)。
4.2 MCTS 的四步循环
| 步骤 | 做什么 | 从零理解 |
|---|---|---|
| 选择 | 从根节点出发,根据 UCB/UCT 一路选择子节点 | 在“看起来好”和“没怎么试过”之间平衡。 |
| 扩展 | 遇到还没完全展开的节点,添加一个或多个新孩子 | 搜索树逐渐长大,而不是一开始就生成全部分支。 |
| 模拟 | 从新节点开始用默认策略走到终局,得到收益 | 默认策略可以是随机策略,也可以是较快的启发式策略。 |
| 回传 | 把这次收益更新到路径上的每个节点 | 访问次数加一,胜利次数或累计收益更新。 |
4.3 节点上到底存什么
一个 MCTS 节点通常至少保存两个统计量:访问次数和累计收益。若从节点 \(s\) 选择行动 \(a\) 到达子节点,则常写作:
如果收益记为胜利次数,\(Q\) 就是胜率;如果收益记为 \(-1,0,1\),\(Q\) 就是平均局面价值。笔记中特别提醒:节点写成“获胜次数/模拟总次数”时,获胜次数是从该节点角度说的;如果题目约定从根节点玩家角度统计,就按题目约定来。
4.4 UCB / UCT:为什么不是永远选胜率最高
如果永远选当前胜率最高的孩子,早期随机好运的分支会被过度利用,其他潜在好分支没有机会被探索。UCB 用一个“利用项 + 探索项”解决这个问题:
- \(\overline{X}_j\):第 \(j\) 个拉杆/子节点目前获得回报的均值,也就是利用项。
- \(n\):到当前时刻为止,总访问次数。
- \(T_j(n)\):第 \(j\) 个拉杆/子节点已经被访问的次数。
- \(\sqrt{2\ln n/T_j(n)}\):探索项。访问越少,探索奖励越大;总访问越多,仍会给没试够的分支机会。
把 UCB 用到树上就常称为 UCT。选择阶段在每个内部节点都计算孩子的 \(I_j\),选 \(I_j\) 最大的孩子向下走。
4.5 UCT 计算小例子
某节点总访问次数 \(n=20\)。三个孩子的“胜利次数/访问次数”分别为 A: \(6/10\),B: \(2/5\),C: \(1/1\)。按笔记公式:
所以本轮会优先选 C。它不只是因为目前胜率高,还因为访问次数太少,探索项很大。
4.6 MCTS 与 \(\alpha\)-\(\beta\) 的区别
| 维度 | \(\alpha\)-\(\beta\) | MCTS |
|---|---|---|
| 基础 | 确定性 minimax 搜索 | 随机采样 + 统计估计 |
| 节点值 | 由叶子估值精确备份得到 | 由多次模拟的平均收益估计 |
| 剪枝/选择 | 用上下界剪去不影响结果的分支 | 用 UCB 在利用和探索之间分配模拟次数 |
| 适合 | 分支较可控、估值函数较可靠的棋类 | 分支巨大、难以手写估值函数、可用模拟评估的任务 |
5. 强化学习、AlphaGo 与 AlphaGo Zero
这一节按补充笔记中的 AlphaGo 公式重新整理:AlphaGo 不是“单纯一个神经网络下棋”,也不是“普通 UCT 直接套用”。它把策略网络、估值网络、快速 rollout 和 MCTS 结合起来,用神经网络减少盲目搜索,用树搜索修正神经网络的一步判断。
5.1 强化学习先抓三句话
状态 \(s\)
当前环境情况。在围棋中就是当前棋盘局面。
动作 \(a\)
智能体可采取的行为。在围棋中就是选择某个位置落子。
回报 \(R\)
动作带来的长期收益。围棋往往到终局才知道胜负。
强化学习学习策略 \(\pi(a\mid s)\):在状态 \(s\) 下应选择动作 \(a\) 的概率或规则。它与监督学习不同:监督学习通常给出“这一步标准答案”,强化学习更多依靠试错和最终回报。
5.2 AlphaGo 中 MCTS 的节点收益:价值网络与 rollout 的混合
在普通 MCTS 中,一次模拟的收益可以直接来自随机走到终局的胜负。AlphaGo 的笔记公式把节点 \(s\) 的第 \(i\) 次模拟收益写成:
- \(value(s)\):估值网络对局面 \(s\) 的输出,表示这个局面最终胜负倾向。
- \(rollout(s)\):从 \(s\) 出发快速模拟一次得到的结果。
- \(\lambda\):混合系数,用来平衡“神经网络估值”和“快速模拟结果”。
因此,AlphaGo 并不是只相信价值网络,也不是只相信随机模拟,而是把两者合成一次模拟收益。
5.3 平均收益 \(Q\):走到某个子局面后平均有多好
设 \(s_a\) 表示在局面 \(s\) 的位置/动作 \(a\) 落子后的新局面。补充笔记中的平均收益为:
这就是“这个落子点已经被模拟过的平均效果”。若某个子局面被模拟很多次且收益高,它的 \(Q\) 会高;但如果只看 \(Q\),仍然可能过早陷入某个看起来好的分支。
5.4 探索项 \(u\):策略网络告诉搜索应该往哪里看
普通 UCT 的探索项是 \(\sqrt{2\ln n/T_j(n)}\)。AlphaGo 的笔记公式改成带策略先验的探索项:
- \(p(s_a)\):策略网络认为在 \(a\) 处落子的概率。概率越高,越值得探索。
- \(N(s)\):父局面 \(s\) 的模拟次数。
- \(N(s_a)\):子局面 \(s_a\) 已被访问的次数。访问越多,探索奖励越小。
- \(c\):加权系数,控制探索强度。
实际选择时,可以理解为选择使下面分数最大的动作:
5.5 AlphaGo 的整体流程
5.6 AlphaGo 与 AlphaGo Zero 的区别
| 项目 | AlphaGo | AlphaGo Zero |
|---|---|---|
| 训练来源 | 先用人类棋谱做监督学习,再通过自我对弈强化 | 从零开始自我对弈,不依赖人类棋谱 |
| 网络结构 | 策略网络、估值网络、rollout policy 等模块较分散 | 一个策略-价值网络同时输出 \(\mathbf p\) 和 \(v\) |
| rollout | 使用快速 rollout 参与收益估计 | 通常不再使用传统快速 rollout,更多依赖价值网络与 MCTS |
| MCTS作用 | 结合策略先验、估值网络和 rollout 修正落子 | MCTS 产生更强的搜索策略 \(\pi\),反过来训练网络 |
5.7 2024真题补强:softmax策略网络如何用 MCTS 次数训练
2024第6题把围棋策略网络简化成“没有隐藏层的 softmax 分类器”。输入 \(x_i(i=1,\ldots,N)\) 表示当前棋局特征;输出 \(p_j(j=1,\ldots,N)\) 表示在第 \(j\) 个点落子的概率;\(m_j\) 是 MCTS 结束后第 \(j\) 个后继局面被选中的次数。题目希望 \(m_j\) 越大,网络输出 \(p_j\) 越大。
第一步:写出前向传播
第二步:把 MCTS 次数变成目标分布
令总访问次数 \(M=\sum_{k=1}^{N}m_k\),目标概率为:
这样 \(q_j\) 就是“搜索认为第 \(j\) 个动作应该被选的比例”。这一步和 AlphaGo Zero 里用 MCTS 搜索策略 \(\pi\) 训练策略头的思想是一致的。
第三步:定义损失函数
这是交叉熵。若某个动作的 MCTS 比例 \(q_j\) 很大,而网络给的 \(p_j\) 很小,\(-q_j\log p_j\) 就会变大,迫使网络提高该动作概率。
第四步:推导梯度和更新式
6. 决策树:ID3 与 C4.5
决策树学习就是从训练集中归纳出一组分类规则,得到一棵与训练集矛盾较小、同时尽量能泛化到新样本的树。它的直观形式是“先问哪个问题,再根据答案继续问”,直到给出类别。
6.1 决策树在学什么
训练集 \(D\) 由很多样本组成,每个样本有若干特征和一个类别。决策树的内部节点是特征测试,边是特征取值,叶节点是类别标记。例如先问“天气=晴/阴/雨”,再问“湿度=高/正常”,最后判断是否打球。
内部节点
选择一个特征,例如 \(A=\) 天气。
分支
特征的不同取值,例如晴、阴、雨。
叶节点
最终类别,例如“是”或“否”。
6.2 熵:当前数据集有多不确定
若训练集 \(D\) 中有 \(K\) 个类别 \(C_1,\ldots,C_K\),类别 \(C_k\) 的样本数为 \(|C_k|\),总样本数为 \(|D|\),则熵为:
熵越大,类别越混杂;熵越小,类别越纯。如果所有样本都属于同一类,熵为 \(0\)。计算时约定 \(0\log 0=0\)。
6.3 条件熵:按某个特征划分后还剩多少不确定
设特征 \(A\) 有 \(n\) 个可能取值 \(a_1,\ldots,a_n\)。按 \(A\) 的取值把 \(D\) 划分为 \(D_1,\ldots,D_n\)。其中 \(D_{ik}\) 表示子集 \(D_i\) 中属于类别 \(C_k\) 的样本集合。笔记中的条件熵公式可写为:
它是“先按特征 \(A\) 分组,再看每组内部还乱不乱”的加权平均。权重 \(|D_i|/|D|\) 不能漏,因为大分支比小分支影响更大。
6.4 信息增益:这个特征让不确定性减少了多少
信息增益越大,说明用特征 \(A\) 划分后,不确定性减少越多。ID3 每一步都选择当前信息增益最大的特征作为当前节点。
6.5 ID3 算法:按笔记整理的递归流程
| 步骤 | 规则 | 考场写法 |
|---|---|---|
| 输入 | 训练集 \(D\)、特征集 \(A\)、阈值 \(\varepsilon>0\) | 先写清候选特征,不要把类别列当特征。 |
| 1 | 若 \(D\) 中所有样本属于同一类 \(C_k\) | 直接标记叶节点为 \(C_k\),停止递归。 |
| 2 | 若特征集 \(A\) 为空 | 标记为 \(D\) 中样本数最多的类别。 |
| 3 | 计算每个特征对 \(D\) 的信息增益 | 选 \(g(D,A)\) 最大的特征 \(A_g\)。 |
| 4 | 若最大信息增益 \(g(D,A_g)<\varepsilon\) | 不再划分,标记为 \(D\) 中多数类。 |
| 5 | 否则按 \(A_g\) 的每个取值 \(a_i\) 划分子集 \(D_i\) | 为每个取值生成一个分支。 |
| 6 | 若某个 \(D_i\) 为空 | 该分支标记为父节点数据集 \(D\) 中多数类。 |
| 7 | 若 \(D_i\) 非空 | 以 \(D_i\) 为训练集、以 \(A-\{A_g\}\) 为特征集递归建树。 |
6.6 完整手算例子:选根节点
考虑 8 条训练样本,类别为“打球=是/否”。候选特征有天气、湿度、风。
| 编号 | 天气 | 湿度 | 风 | 打球 |
|---|---|---|---|---|
| 1 | 晴 | 高 | 弱 | 否 |
| 2 | 晴 | 高 | 强 | 否 |
| 3 | 阴 | 高 | 弱 | 是 |
| 4 | 雨 | 高 | 弱 | 是 |
| 5 | 雨 | 正常 | 弱 | 是 |
| 6 | 雨 | 正常 | 强 | 否 |
| 7 | 阴 | 正常 | 强 | 是 |
| 8 | 晴 | 正常 | 弱 | 是 |
总数据集中“是”有 5 个,“否”有 3 个:
| 特征 | 划分情况 | 条件熵 | 信息增益 |
|---|---|---|---|
| 天气 | 晴: 1是2否;阴: 2是0否;雨: 2是1否 | \(\frac38\cdot0.918+\frac28\cdot0+\frac38\cdot0.918\approx0.689\) | \(0.954-0.689=0.265\) |
| 湿度 | 高: 2是2否;正常: 3是1否 | \(\frac48\cdot1+\frac48\cdot0.811\approx0.906\) | \(0.048\) |
| 风 | 弱: 4是1否;强: 1是2否 | \(\frac58\cdot0.722+\frac38\cdot0.918\approx0.795\) | \(0.159\) |
最大信息增益来自“天气”,所以 ID3 选择“天气”作为根节点。接着每个分支继续递归:例如“阴”分支全是“是”,可直接成为叶节点;“晴”和“雨”分支仍有混杂,需要继续选剩余特征。
6.7 C4.5:为什么要从信息增益改成信息增益比
ID3 的一个重要问题是:它偏爱取值很多的属性。极端地说,如果有一个“编号”特征,每个样本编号都不同,那么按编号划分后每个子集只有一个样本,条件熵为 0,信息增益会非常大,但这显然只是记住训练集,不能泛化。
C4.5 用信息增益比来惩罚这种“分支过多”的属性。先定义属性 \(A\) 自身造成的划分熵:
\(H_A(D)\) 越大,说明这个属性把数据切得越碎;除以它之后,可以降低多取值属性的虚高优势。
6.8 连续属性怎么处理
如果特征是连续值,例如“年龄”“收入”,不能像离散属性那样直接按每个数值开分支。常见做法是把连续属性转成二分测试:
- 把样本按该连续特征从小到大排序。
- 在相邻不同取值之间取候选阈值,例如 \(t=(a_i+a_{i+1})/2\)。
- 对每个候选阈值计算划分后的信息增益或增益比。
- 选择最好的阈值作为该节点的测试条件。
6.9 剪枝:防止过拟合
树长得太深时,可能把训练集里的偶然噪声也记住,导致新样本表现变差。C4.5 常配合后向剪枝:先长出较完整的树,再自底向上检查某些子树是否应替换为叶节点。如果替换后验证误差或估计泛化误差更好,就剪掉该子树。
6.10 2024真题同型例题:两特征数据集完整计算
2024第5题的数据集如下。类别 Y 有3个,N 有3个,所以总体最混杂:
| 序号 | 特征 A | 特征 B | 类别 |
|---|---|---|---|
| 1 | T | T | N |
| 2 | T | T | N |
| 3 | T | F | Y |
| 4 | F | F | N |
| 5 | F | T | Y |
| 6 | F | T | Y |
第一步:总体熵
第二步:按特征 A 划分
\(A=T\) 子集有 N,N,Y;\(A=F\) 子集有 N,Y,Y。两个子集都是 2:1 混合,熵相同:
A 的取值比例是 3:3,所以划分熵为 \(H_A(D)=1\),信息增益比约为 \(0.082\)。
第三步:按特征 B 划分
\(B=T\) 子集有 N,N,Y,Y,熵为1;\(B=F\) 子集有 Y,N,熵也为1:
如果题目继续要求画树
根节点选 A 后,两个分支都可以继续用 B 完全分开:
也就是说这个训练集的类别规律等价于“\(A\) 与 \(B\) 不同时为 Y,相同时为 N”。但考试第一问通常只要求第一步选哪个特征,别忘了把信息增益和信息增益比都列出来。
7. 考场作答模板
7.1 \(\alpha\)-\(\beta\) 剪枝模板
1. 标层:根为 MAX / MIN,后续交替。 2. 从左到右访问叶子,不要擅自换顺序。 3. MAX 节点维护下界 alpha:已看孩子的最大值。 4. MIN 节点维护上界 beta:已看孩子的最小值。 5. 继承祖先边界;比较对象不只父节点。 6. 若 alpha >= beta:剪去当前节点剩余未访问孩子,并在图上画叉。 7. 所有未剪部分算完后,在每个内部节点旁写最终值。 8. 根节点按 MAX / MIN 规则选最终走步。
7.2 A*/修正A*模板
表格列:step | OPEN | CLOSED | fm | NEST | expand | generated/updated | parent
普通 A*: 每步选 OPEN 中 f=g+h 最小节点。
修正 A*: 先找 NEST={n in OPEN | f(n)<fm};
NEST 非空选其中 g 最小,否则选 OPEN 最小 f 并更新 fm。
结束:被选中的节点是目标,而不是目标刚生成。
路径:目标沿父指针回溯到起点。
7.3 MCTS / UCT模板
四步:选择 -> 扩展 -> 模拟 -> 回传。 节点统计:访问次数 N,累计收益 W,平均收益 Q=W/N。 UCT:I_j = Xbar_j + sqrt(2 ln n / T_j(n))。 含义:第一项是利用,第二项是探索。 做题:对每个候选孩子算 I_j,选最大的继续向下。
7.4 AlphaGo模板
一次模拟收益:v_i(s)=lambda*value(s)+(1-lambda)*rollout(s)。 平均收益:Q(s_a)=sum_i v_i(s_a)/n。 探索项:u(s_a)=c*p(s_a)*sqrt(N(s))/(N(s_a)+1)。 选择:比较 Q(s_a)+u(s_a)。 解释:value 来自估值网络;rollout 是快速模拟;p 来自策略网络。
7.5 模拟退火模板
当前能量 Ecur。
对每个候选 Enew:
Delta = Enew - Ecur。
若 Delta <= 0: 接受,Ecur = Enew。
若 Delta > 0: p = exp(-Delta/T)。若随机数 r < p 接受,否则拒绝。
接受率 = 接受次数 / 尝试次数。
注意:拒绝后 Ecur 不变。
7.6 遗传算法模板
轮盘赌: 1. 求总适应值 F。 2. 每个个体概率 p_i=f_i/F。 3. 写累积区间。 4. 每个随机数落在哪个区间,就选择哪个个体。 确定性: 1. 期望复制数 e_i=N f_i/F。 2. 先取整数部分。 3. 剩余名额按小数部分从大到小补足。 4. 后续按题目给定交叉/变异规则操作。
7.7 ID3 / C4.5模板
ID3: 1. 统计总数据集 D 的类别数量,算 H(D)。 2. 对每个特征 A,按取值分组 D_i。 3. 每组算 H(D_i),加权得 H(D|A)。 4. 信息增益 g(D,A)=H(D)-H(D|A)。 5. 选 g 最大的特征作为当前节点。 6. 分支纯净则标叶;不纯则递归。 7. 若特征用完、子集为空或增益低于阈值,标多数类。 C4.5: 1. ID3 的问题:偏好多取值属性,不能直接处理连续属性。 2. 信息增益比 g_R(D,A)=g(D,A)/H_A(D)。 3. 连续属性用阈值 A<=t / A>t 划分。 4. 防止过拟合:后向剪枝。
7.8 2024策略网络/softmax模板
输入:棋局特征 x_i;输出:每个候选落子点概率 p_j;MCTS 次数 m_j。 1. net_j = sum_i w_ji x_i + b_j。 2. p_j = exp(net_j) / sum_k exp(net_k)。 3. M = sum_k m_k,q_j = m_j / M。 4. L = - sum_j q_j log p_j。 5. softmax + 交叉熵结论:dL/dnet_j = p_j - q_j。 6. dL/dw_ji = (p_j - q_j) x_i;dL/db_j = p_j - q_j。 7. 梯度下降:w_ji <- w_ji - eta (p_j - q_j)x_i。
8. 自测题与复习路线
8.1 一天速成路线
- 1小时:读第1节题型地图,知道每题交什么。
- 2小时:练 A*/修正A*,至少手算2个图。
- 2小时:练 \(\alpha\)-\(\beta\) 剪枝,重点是不齐树、从左到右、祖先边界。
- 1小时:练 MCTS/UCT,至少会代入 \(\overline X_j+\sqrt{2\ln n/T_j(n)}\)。
- 1小时:背 AlphaGo 的 \(v_i\)、\(Q\)、\(u\) 三个公式,以及 2024 softmax策略网络的 \(p_j-q_j\) 梯度。
- 2小时:练 ID3/C4.5,至少完整算一次信息增益并能解释信息增益比。
- 30分钟:背模拟退火、遗传算法模板。
8.2 三天稳妥路线
第1天:图搜索
DFS/BFS/Dijkstra/A/A*/修正A*;重点练 OPEN/CLOSED 表、父指针、NEST 与 \(f_m\)。
第2天:博弈与随机搜索
\(\alpha\)-\(\beta\)、MCTS、AlphaGo;重点练上下界剪枝、UCT 计算、\(Q+u\) 解释。
第3天:机器学习与随机优化
ID3/C4.5、模拟退火、遗传算法;重点练熵、条件熵、信息增益、增益率和概率接受。
8.3 考前检查清单
- 我能解释 \(g,h,f\),并知道A*何时结束。
- 我能写出单调性条件,并说明单调推出A*条件、避免重复扩展。
- 我能按修正A*规则计算 NEST 和 \(f_m\)。
- 我能独立做一棵不齐树的 \(\alpha\)-\(\beta\) 剪枝,并说明剪枝依据来自祖先边界。
- 我能写出 MCTS 四步和 UCT 中探索/利用两项。
- 我能说清 AlphaGo 中 \(value(s)\)、\(rollout(s)\)、\(Q(s_a)\)、\(u(s_a)\)、\(p(s_a)\) 的作用,并能把 MCTS 次数 \(m_j\) 转为策略网络目标 \(q_j\)。
- 我能从数据表中算出 \(H(D)\)、\(H(D\mid A)\)、\(g(D,A)\),并选出 ID3 根节点。
- 我能解释 C4.5 为什么使用信息增益比,以及如何处理连续属性和过拟合。
- 我能根据温度、能量差和随机数判断模拟退火是否接受。
- 我能根据适应值和随机数完成遗传算法选择步骤。
8.4 最小自测题
题1:为什么 \(\alpha\)-\(\beta\) 剪枝不改变 minimax 结果?
因为被剪掉的分支已经不可能改变某个祖先的选择。例如 MAX 祖先已经能保证 \(\alpha\),当前 MIN 后辈已经有 \(\beta\le\alpha\),则 MIN 会让该分支值不超过 \(\beta\),根本不会让 MAX 得到更好选择。
题2:UCT 公式里为什么访问次数少的子节点更容易被选?
探索项 \(\sqrt{2\ln n/T_j(n)}\) 中,\(T_j(n)\) 在分母。访问次数越少,探索项越大,算法会给不确定分支更多机会。
题3:ID3 为什么偏好多取值属性?C4.5 怎么修正?
多取值属性容易把数据切得很碎,使每个子集熵很低,从而信息增益虚高。C4.5 用信息增益比 \(g_R(D,A)=g(D,A)/H_A(D)\) 惩罚划分过碎的属性。
9. 来源与取舍说明
本版在原 HTML 的基础上重写和扩充了“对抗搜索与 \(\alpha\)-\(\beta\) 剪枝”“蒙特卡洛方法与 MCTS”“AlphaGo”三节,并按补充笔记替换为“决策树:ID3 与 C4.5”内容。本次又根据 2024 真题第1、2、5、6题补充了不齐 \(\alpha\)-\(\beta\) 树、修正A*完整表、决策树小数据集计算、softmax策略网络训练推导;按要求未纳入第3题 SVM 与第4题 GoogleNet/Inception。
2013年及以前的旧题包含 AO*、专家系统、归结、逆向演绎、SOM 等内容。根据当前复习重点,本指南优先保留 A/A*/修正A*、\(\alpha\)-\(\beta\) 剪枝、MCTS、AlphaGo、模拟退火、遗传算法、ID3/C4.5。已单独整理的内容没有再放入本文件,以免挤占核心题型复习时间。
AlphaGo 部分采用补充笔记中的写法:一次模拟收益 \(v_i(s)=\lambda value(s)+(1-\lambda)rollout(s)\),平均收益 \(Q(s_a)\),以及带策略先验的探索项 \(u(s_a)=c p(s_a)\sqrt{N(s)}/(N(s_a)+1)\)。决策树部分采用笔记中的熵、条件熵、信息增益、ID3递归终止条件、C4.5信息增益比和后向剪枝框架。