10057 字
50 分钟
OceanAI-Chpater3:搜索探寻与问题求解

概述#

这一章的核心是:

面对数量庞大的候选方案,智能体需要把问题表示为状态空间,并在有限时间、有限内存下,决定 先探索哪些分支、放弃哪些分支,最终找到可行解或尽可能好的解。

整章知识链条可以概括为:

  1. 一般搜索:把任务写成状态、动作、状态转移、路径代价与目标测试。
  2. 启发式搜索:利用额外信息判断哪个候选结点更值得优先扩展。
  3. 对抗搜索:把会主动反制的对手纳入搜索,求双方理性行动下的最优策略。
  4. 蒙特卡洛树搜索:当搜索树大到无法穷举时,通过随机采样和统计估计逐步逼近较优决策。

几类算法最重要的评价规则为:

算法优先依据核心表达
深度优先搜索当前分支继续向深处走无启发信息
广度优先搜索先扩展浅层结点无启发信息
贪婪最佳优先搜索估计离目标最近f(n)=h(n)f(n)=h(n)
A* 搜索已付代价与未来估计之和最小f(n)=g(n)+h(n)f(n)=g(n)+h(n)
MinimaxMAX 最大化、MIN 最小化V(s)=max/minV(s)V(s)=\max/\min V(s')
UCB / UCT平均收益高且不确定性大的分支均值项 ++ 探索项

目录#


搜索问题的统一框架#

搜索的直观本质#

搜索算法的任务可以理解为:

从一个初始状态出发,不断选择动作并产生新状态,在大量可能路径中找到通向目标状态的路径。

路径规划、机器人控制、棋类博弈、任务分解等问题表面上差别很大,内部结构却相似:

  • 系统当前处于某个 状态
  • 当前状态下有若干可执行 动作
  • 动作使系统发生 状态转移
  • 一串动作形成一条 路径
  • 路径会产生时间、距离、金钱或风险等 代价
  • 算法通过 目标测试 判断任务是否完成。

搜索算法真正需要解决的是:

  1. 下一步先扩展哪个结点;
  2. 哪些结点没有必要继续扩展;
  3. 如何在解的质量与计算资源之间权衡。

搜索问题的形式化描述#

一个搜索问题通常由以下要素构成:

S,s0,A,Result,Goal,c\langle S,s_0,A,\operatorname{Result},\operatorname{Goal},c\rangle

state:状态#

状态 sSs\in S 描述系统当前与后续决策有关的情形。

状态应保留完成任务所必需的信息,同时删去无关细节。不同问题中的状态可以是:

  • 路径规划中的当前位置;
  • 八数码问题中的棋盘布局;
  • 博弈问题中的棋盘局面与当前行动方。

其中:

  • SS:状态空间,所有可能状态的集合;
  • s0s_0:初始状态;
  • 目标状态:满足任务要求的状态。

action:动作#

动作表示在当前状态下可执行的操作。

A(s)={状态 s 下可执行的动作}A(s)=\{\text{状态 }s\text{ 下可执行的动作}\}

动作通常按一次决策来离散地描述。例如“从舟山乘大巴到杭州”可以看作一个动作。

state transition:状态转移#

状态转移函数描述执行动作后系统到达哪里:

s=Result(s,a)s'=\operatorname{Result}(s,a)

动作回答“做什么”,状态转移回答“做完后到哪里”。

path:路径#

从初始状态出发,依次执行动作

a0,a1,,ak1a_0,a_1,\ldots,a_{k-1}

并得到状态序列

s0,s1,,sk,si+1=Result(si,ai)s_0,s_1,\ldots,s_k, \qquad s_{i+1}=\operatorname{Result}(s_i,a_i)

这一状态序列及其对应动作序列构成一条路径。

cost:路径代价#

单步代价记为

c(si,ai,si+1)0c(s_i,a_i,s_{i+1})\ge 0

从初始状态到结点 n=skn=s_k 的累计路径代价为

g(n)=i=0k1c(si,ai,si+1)g(n)=\sum_{i=0}^{k-1}c(s_i,a_i,s_{i+1})

代价可以表示:

  • 行驶时间;
  • 路程;
  • 票价;
  • 能量消耗;
  • 风险;
  • 多个指标的加权结果。
WARNING

路径步数与路径代价必须区分。

路径更短,不代表总代价更小。例如一条路经过的路口少,却可能严重拥堵;另一条路绕得更远,却可能更快。

goal test:目标测试#

目标测试函数判断当前状态是否满足任务目标:

Goal(s)={true,s 是目标状态 false,否则\operatorname{Goal}(s)= \begin{cases} \text{true}, & s\text{ 是目标状态}\ \text{false}, & \text{否则} \end{cases}

目标测试只回答“是否到达目标”。

它不能单独判断当前路径是否为最优路径。算法第一次找到目标后是否可以立即停止,取决于具体搜索策略及其最优性保证。

例:舟山到杭州#

老师用“从舟山到杭州”说明搜索问题的各个组成部分。

  • 初始状态:人在舟山;
  • 目标状态:到达杭州;
  • 动作:乘大巴、乘高铁、换乘等;
  • 状态转移:执行交通动作后,从一个城市到达另一个城市;
  • 路径 1:舟山 \rightarrow 杭州;
  • 路径 2:舟山 \rightarrow 宁波 \rightarrow 杭州;
  • 代价:总时间、总票价或二者的综合;
  • 目标测试:当前位置是否为杭州。

若路径 1 直接乘大巴,需要一个单步代价;路径 2 在宁波换乘,则总代价为两个单步代价之和:

C舟山宁波+C宁波杭州C_{\text{舟山}\to\text{宁波}}+C_{\text{宁波}\to\text{杭州}}

该例说明:同一个目标可以由多条路径到达,算法需要在这些路径之间作出选择。

状态、结点、搜索树与搜索图#

搜索树#

搜索过程可以看作一棵搜索树的逐步构建:

  • 根结点对应初始状态;
  • 每次扩展一个结点,就生成其后继结点;
  • 每条根到结点的路径,对应一种动作序列;
  • 当某个结点通过目标测试时,找到一条解路径。

配图占位:插入第 3 章 PPT 第 9 页“搜索过程可视为搜索树的构建”。重点保留同一状态 A 通过不同路径重复出现的示意图。

状态与结点的区别#

  • 状态:只描述系统当前情形;
  • 结点:搜索树中的记录单元,还包含到达该状态的路径、父结点与累计代价等信息。

因此,不同结点可以对应同一个状态。

例如下列三条路径都回到了状态 A:

ABAA\rightarrow B\rightarrow AADAA\rightarrow D\rightarrow AAEAA\rightarrow E\rightarrow A

搜索树中会出现三个标记为 A 的结点,因为它们记录了三条不同路径。

搜索图#

若将所有相同状态合并,并记录某个状态是否已经访问过,就得到搜索图的观点。

  • 树搜索:按路径展开,同一状态可能被多次生成;
  • 图搜索:检查重复状态,避免无意义的反复访问。

图搜索通常需要维护已访问状态,并在发现同一状态的更优路径时决定是否更新。

OPEN、CLOSED 与结点扩展#

搜索算法通常维护两个集合。

OPEN / frontier:边缘集合、开表#

OPEN 保存:

已经生成、尚未扩展、以后仍可能被选中的全部候选结点。

它不只包含“刚扩展结点的孩子”,还包含之前保留下来的其他候选结点。

CLOSED / explored:已扩展集合、闭表#

CLOSED 保存已经被取出并完成扩展的结点或状态,用于:

  • 记录搜索历史;
  • 检测环路;
  • 处理重复状态。

expand:结点扩展#

扩展结点 nn 通常包括:

  1. 从 OPEN 中取出 nn
  2. nn 进行目标测试;
  3. 若尚未到达目标,生成 nn 的合法后继;
  4. 按规则将后继加入 OPEN;
  5. nn 记入 CLOSED。

统一搜索框架可以写成:

OPEN ← {初始结点}
CLOSED ← ∅
while OPEN 非空:
n ← 从 OPEN 中按某种规则选一个结点
从 OPEN 中删除 n
if Goal(n):
return 从初始结点到 n 的路径
将 n 加入 CLOSED
生成 n 的合法后继
将需要保留的后继加入 OPEN
return 搜索失败

不同算法最主要的区别集中在两处:

  • pick_from(OPEN):下一步从 OPEN 中选谁;
  • successor_nodes(n):哪些后继可以进入 OPEN,哪些需要剪枝。

老师强调的 OPEN 例子#

设初始时:

OPEN=[1]\operatorname{OPEN}=[1]

扩展结点 1,生成结点 2、3、4:

OPEN=[2,3,4]\operatorname{OPEN}=[2,3,4]

接着取出结点 2,并生成结点 5、6。此时:

OPEN=[5,6,3,4]\operatorname{OPEN}=[5,6,3,4]

其中 3、4 仍在 OPEN 中,并不会因为算法开始探索 2 的后继就消失。

WARNING

OPEN 是当前全部候选结点的集合。

做搜索过程题时,最常见的错误是只保留刚生成的孩子,漏掉先前尚未扩展的兄弟结点。

剪枝#

剪枝(pruning)指根据某种判据,提前停止对一部分结点或分支的扩展。

核心目的:

  • 避免死循环;
  • 减少无效计算;
  • 把资源集中到更有希望的分支;
  • 在不改变最终结果的条件下压缩搜索树。

环路剪枝#

若路径出现

ABABA\rightarrow B\rightarrow A\rightarrow B\rightarrow\cdots

算法可能永远在 A 与 B 之间循环。

只要发现新状态已经出现在当前路径的祖先中,就可以停止扩展该分支。

劣势分支剪枝#

若某个分支即使继续展开,也不可能优于当前已有结果,则可以直接剪去。

例如从舟山去杭州时,“舟山 \rightarrow 北京 \rightarrow 杭州”通常明显劣于更直接的路线,可以在有可靠判据时放弃。

后面的 Alpha-Beta 剪枝就是这种思想在博弈树中的严格实现。

配图占位:插入第 3 章 PPT 第 12 页“搜索树构建示意”。保留实线结点、虚线边缘结点及环路剪枝示意。

搜索算法的评测标准#

completeness:完备性#

当问题存在解时,算法是否保证最终找到一个解。

完备性只保证“能找到”,不保证“找到的是最好解”。

optimality:最优性#

算法找到的第一个解是否一定为最优解。

最优的具体含义由代价函数决定,例如:

  • 路程最短;
  • 时间最少;
  • 总费用最低。

time complexity:时间复杂度#

通常用算法扩展的结点数量衡量。

space complexity:空间复杂度#

通常用算法运行过程中同时保存的结点数量衡量。

搜索复杂度常与以下量有关:

符号含义
bb分支因子,每个结点最多生成多少个孩子
dd最浅目标结点的深度
mm搜索树中路径的最大可能长度
NN状态空间中的状态数量

若每个结点平均有 bb 个孩子,搜索到深度 dd,结点数约为

1+b+b2++bd=bd+11b11+b+b^2+\cdots+b^d =\frac{b^{d+1}-1}{b-1}

b>1b>1 时,结点数随深度呈指数增长,这就是 组合爆炸 的根源。

无信息搜索:深度优先与广度优先#

老师在讲启发式搜索前,用深度优先搜索与广度优先搜索作对比。

它们都不使用“哪个结点离目标更近”等额外知识,因此属于 无信息搜索(uninformed search)。

depth-first search:深度优先搜索#

  • 沿当前分支持续向深处探索;
  • 走不通时回溯到最近的分叉点;
  • 类似走迷宫时始终优先走最右边的一条路,走到尽头再退回。

优点:占用内存较少。

局限:可能沿错误分支走得很深,也可能陷入环路;若没有深度限制和去重机制,不一定完备。

breadth-first search:广度优先搜索#

  • 先扩展当前层全部结点;
  • 再进入下一层;
  • 搜索过程按“由近到远”逐层推进。

优点:在每步代价相同时,第一个找到的解是最少步数解。

局限:需要同时保存大量边缘结点,空间消耗较大。

本章课堂重点不在两者的具体实现,理解它们与启发式搜索的区别即可:

无信息搜索按固定结构展开;启发式搜索使用额外信息决定优先扩展方向。


启发式搜索#

启发信息、启发函数与评价函数#

利用与问题相关的额外信息指导搜索,称为:

  • 有信息搜索(informed search);
  • 启发式搜索(heuristic search)。

例如,在地图中用“当前城市到目标城市的直线距离”判断哪个城市更有希望。

heuristic function:启发函数#

启发函数 h(n)h(n) 估计:

从当前结点 nn 到目标结点还需要付出多少代价。

记真实最小剩余代价为 h(n)h^*(n),则

h(n)h(n)h(n)\approx h^*(n)

地图搜索中常用直线距离或按最大速度估计的最短时间作为 h(n)h(n)

path-cost function:路径代价函数#

g(n)=从初始结点到当前结点 n 已经付出的真实累计代价g(n)=\text{从初始结点到当前结点 }n\text{ 已经付出的真实累计代价}

evaluation function:评价函数#

评价函数 f(n)f(n) 决定:

OPEN 中哪个结点应当优先扩展。

通常 f(n)f(n) 越小,优先级越高。

WARNING

启发函数与评价函数不是同一个概念。

  • h(n)h(n) 负责估计“未来还要多少”;
  • f(n)f(n) 负责决定“下一个选谁”。

只有在贪婪最佳优先搜索中,二者恰好相等:f(n)=h(n)f(n)=h(n)

贪婪最佳优先搜索#

贪婪最佳优先搜索(Greedy Best-First Search)的评价函数为

f(n)=h(n)f(n)=h(n)

算法每次从 OPEN 中选择 h(n)h(n) 最小的结点,也就是选择“看起来离目标最近”的结点。

基本流程#

  1. 将初始结点加入 OPEN;
  2. 从 OPEN 中取出 h(n)h(n) 最小的结点;
  3. 若通过目标测试,返回路径;
  4. 否则扩展该结点,把合法后继加入 OPEN;
  5. 重复以上过程。

例:从城市 A 到城市 K#

PPT 中给出城市 A 到 K 的交通图,边上的数字为实际行驶代价,各城市到 K 的直线距离作为启发函数:

结点AABBCCDDEEFFGGHHIIJJKKLL
h(n)h(n)131061278536306

配图占位:插入第 3 章 PPT 第 14 页右侧“城市 A 到 K 的交通网络图”与启发函数表。

搜索过程:

  1. 扩展 A,生成 B、D、E:

    h(B)=10,h(D)=12,h(E)=7h(B)=10,\quad h(D)=12,\quad h(E)=7

    选择 E。

  2. 扩展 E,生成 H、G、I:

    h(H)=3,h(G)=5,h(I)=6h(H)=3,\quad h(G)=5,\quad h(I)=6

    OPEN 中还保留 B、D。当前最小值为 h(H)=3h(H)=3,选择 H。

  3. 扩展 H,生成 G、J。因为

    h(J)=3h(J)=3

    贪婪策略继续选择 J。

  4. 扩展 J,生成 K,且

    h(K)=0h(K)=0

    找到路径

    AEHJKA\rightarrow E\rightarrow H\rightarrow J\rightarrow K

这条路径能够到达目标,但总代价为

6+4+7+3=206+4+7+3=20

真正更短的路径为

AEGKA\rightarrow E\rightarrow G\rightarrow K

总代价为

6+3+5=146+3+5=14

配图占位:插入第 3 章 PPT 第 14—15 页“贪婪最佳优先搜索过程”。建议保留各阶段 OPEN 表和结点下方的 h(n)h(n)

为什么会失败#

贪婪最佳优先搜索只关注

h(n)h(n)

没有考虑已经付出的代价

g(n)g(n)

虽然 J 离目标的估计距离很小,h(J)=3h(J)=3,但到达 J 时已经付出

g(J)=17g(J)=17

继续沿 J 前进不可能得到总代价 14 的最短路径。

性质#

  • 在有限状态空间中,若进行环路与重复状态检测,通常能够找到一个解;
  • 不保证最优性;
  • 最坏时间复杂度和空间复杂度都可能达到
O(bm)O(b^m)

贪婪搜索的优势是直观、常常较快,适合先尽快找到一个可行解;缺点是容易被局部上“看起来更近”的方向误导。

A* 搜索#

A* 同时考虑:

  • 已经付出的真实代价 g(n)g(n)
  • 从当前结点到目标的估计代价 h(n)h(n)

评价函数为

f(n)=g(n)+h(n)\boxed{f(n)=g(n)+h(n)}

其含义是:

估计总成本=已经付出的成本+预计还要付出的成本\text{估计总成本} = \text{已经付出的成本} + \text{预计还要付出的成本}

每次从 OPEN 中选择 f(n)f(n) 最小的结点扩展。

与其他算法的关系#

  • 若只看 h(n)h(n),得到贪婪最佳优先搜索;
  • 若令 h(n)=0h(n)=0,A* 退化为只按 g(n)g(n) 排序的一致代价搜索;
  • h(n)=h(n)h(n)=h^*(n),即准确知道真实剩余最小代价,搜索会高度集中在最优路径附近。

例:城市 A 到 K#

第一步:扩展 A#

生成 B、D、E:

f(B)=g(B)+h(B)=5+10=15f(B)=g(B)+h(B)=5+10=15f(D)=3+12=15f(D)=3+12=15f(E)=6+7=13f(E)=6+7=13

因此选择 E。

第二步:扩展 E#

生成 H、G、I:

f(H)=10+3=13f(H)=10+3=13f(G)=9+5=14f(G)=9+5=14f(I)=13+6=19f(I)=13+6=19

当前选择 H。

第三步:扩展 H#

生成后继,其中:

f(J)=17+3=20f(J)=17+3=20

此时 OPEN 中仍有此前生成的 G:

f(G)=14f(G)=14

因此 A* 不继续沿 H 走向 J,而回到 OPEN 中选择 G。

第四步:扩展 G#

G 的后继中包含 K:

f(K)=g(K)+h(K)=14+0=14f(K)=g(K)+h(K)=14+0=14

K 通过目标测试,得到最短路径

AEGK\boxed{A\rightarrow E\rightarrow G\rightarrow K}

总代价为 14。

配图占位:插入第 3 章 PPT 第 18 页“A* 搜索算法搜索过程”。需保留每个边缘结点下方的 g(n)+h(n)=f(n)g(n)+h(n)=f(n)

TIP

A* 的搜索过程不一定沿当前结点的孩子一直向下。

扩展 H 后,下一步可以转而扩展早已存在于 OPEN 中的 G。每一步比较的是 整个 OPEN 中所有候选结点的 f(n)f(n)

A* 图搜索的更新规则#

对后继结点 nn',先计算新的候选路径代价

t=g(n)+c(n,a,n)t=g(n)+c(n,a,n')

nn' 尚未出现,或新路径更优,即

t<g(n)t<g(n')

则更新:

g(n)tg(n')\leftarrow tf(n)g(n)+h(n)f(n')\leftarrow g(n')+h(n')

并更新其父结点。必要时应把已经进入 CLOSED 的状态重新放回 OPEN。

可容性与一致性#

A* 的表现取决于启发函数 h(n)h(n) 的质量。

admissible:可容性#

若对任意结点 nn

0h(n)h(n)0\le h(n)\le h^*(n)

且目标结点满足

h(goal)=0h(\text{goal})=0

则称 h(n)h(n) 可容。

直观含义:

启发函数可以低估真实剩余代价,但不能高估。

例如,两地之间的直线距离通常不大于真实道路距离,因此可以作为可容的距离启发。

consistent:一致性#

若对任意结点 nn、动作 aa 及后继结点 nn'

h(n)c(n,a,n)+h(n)\boxed{h(n)\le c(n,a,n')+h(n')}

则称 h(n)h(n) 一致。

这相当于三角不等式:

nn 直接估计到目标的代价,不应超过“先走一步到 nn' 的真实代价 + 从 nn' 到目标的估计代价”。

一致性蕴含可容性#

设从 n1n_1 到目标 K 的最优路径为

n1n2Kn_1\rightarrow n_2\rightarrow\cdots\rightarrow K

由一致性:

h(n1)c(n1,a1,n2)+h(n2)h(n_1)\le c(n_1,a_1,n_2)+h(n_2)

继续展开:

h(n1)c(n1,a1,n2)+c(n2,a2,n3)++h(K)h(n_1) \le c(n_1,a_1,n_2)+c(n_2,a_2,n_3)+\cdots+h(K)

因为

h(K)=0h(K)=0

所以

h(n1)h(n1)h(n_1)\le h^*(n_1)

因此:

一致性可容性\boxed{\text{一致性}\Rightarrow\text{可容性}}

一致性要求更严格;可容性不一定推出一致性。

A* 搜索的完备性与最优性#

完备性#

若满足以下条件,A* 是完备的:

  1. 每个结点的分支数有限;

  2. 单步代价存在正下界,即存在 ε>0\varepsilon>0,使

    c(n,a,n)εc(n,a,n')\ge\varepsilon
  3. 启发函数有下界,通常令 h(n)0h(n)\ge0

这些条件排除了“单层无限分叉”和“通过无穷多次几乎零代价动作一直拖延”等病态情况。

最优性#

课程中的核心结论是:

若启发函数可容,A* 找到的第一个目标结点对应最优路径。

证明思路:

设最优路径总代价为 CC^*。在最优目标被找到前,最优路径上总有某个边缘结点 nn 留在 OPEN 中。由于可容:

f(n)=g(n)+h(n)g(n)+h(n)=Cf(n)=g(n)+h(n)\le g(n)+h^*(n)=C^*

任何非最优目标 G 都满足

f(G)=g(G)>Cf(G)=g(G)>C^*

A* 总是先扩展最小的 ff,所以非最优目标不可能抢在最优路径的边缘结点之前被取出。

NOTE

严格区分树搜索与图搜索:

  • 树搜索版 A*:可容性足以保证最优性;
  • 图搜索版 A*:通常要求启发函数一致,或允许在发现更小的 gg 时重新打开 CLOSED 中的结点。

一致性保证沿路径的 ff 值非递减,使结点第一次从 OPEN 中取出时,其最优路径代价已经稳定。

复杂度#

即使使用启发函数,A* 在最坏情况下的时间与空间复杂度仍可能是指数级。

  • h(n)h(n) 越接近 h(n)h^*(n),扩展结点通常越少;
  • h(n)0h(n)\approx0,A* 接近一致代价搜索,启发作用很弱;
  • A* 的主要实际瓶颈往往是 OPEN 占用的内存。

贪婪搜索与 A* 搜索对比#

对比项贪婪最佳优先搜索A* 搜索
评价函数f(n)=h(n)f(n)=h(n)f(n)=g(n)+h(n)f(n)=g(n)+h(n)
是否考虑已付代价
是否考虑未来估计
搜索倾向尽快靠近目标平衡过去成本与未来成本
完备性有限空间且排除环路时通常完备满足相关条件时完备
最优性不保证启发函数满足条件时保证
城市例结果AEHJKA\to E\to H\to J\to K,代价 20AEGKA\to E\to G\to K,代价 14

对抗搜索#

对抗搜索的基本设定#

前面的路径搜索面对的是被动环境。博弈问题中存在会主动反制的对手,因此当前动作的价值还取决于对手随后会怎样选择。

对抗搜索(adversarial search)也称博弈搜索(game search)。课程主要讨论:

  • 完全信息;
  • 确定性;
  • 两名玩家轮流行动;
  • 二人零和;
  • 双方都理性地选择最优动作。

其中:

  • MAX:希望最大化效用;
  • MIN:希望最小化 MAX 的效用。

一个博弈问题可以表示为

S,s0,A,Player,Result,Terminal,U\langle S,s_0,A,\operatorname{Player},\operatorname{Result},\operatorname{Terminal},U\rangle
要素含义
ss当前局面与轮到哪一方行动
s0s_0初始局面与先手玩家
A(s)A(s)当前玩家的合法动作集合
Result(s,a)\operatorname{Result}(s,a)执行动作后的后继状态
Player(s)\operatorname{Player}(s)当前行动方是 MAX 还是 MIN
Terminal(s)\operatorname{Terminal}(s)游戏是否结束
U(s)U(s)终局状态对 MAX 的效用

二人零和博弈只需记录 MAX 的效用。MIN 的收益可由相反数得到。

Minimax 搜索#

Minimax 的核心思想是:

MAX 选择使自己最终收益最大的分支,同时假设 MIN 会选择使 MAX 收益最小的分支。

递推公式#

V(s)V(s) 为双方都采用最优策略时,状态 ss 对 MAX 的价值:

V(s)={U(s),Terminal(s)=truemaxaA(s)V(Result(s,a)),Player(s)=MAXminaA(s)V(Result(s,a)),Player(s)=MINV(s)= \begin{cases} U(s), & \operatorname{Terminal}(s)=\text{true}\\[4pt] \displaystyle\max_{a\in A(s)}V(\operatorname{Result}(s,a)), & \operatorname{Player}(s)=\mathrm{MAX}\\[10pt] \displaystyle\min_{a\in A(s)}V(\operatorname{Result}(s,a)), & \operatorname{Player}(s)=\mathrm{MIN} \end{cases}

若根结点由 MAX 行动,则最优动作是

a=argmaxaA(s0)V(Result(s0,a))a^*=\arg\max_{a\in A(s_0)}V(\operatorname{Result}(s_0,a))

Minimax 的计算方向为:

  1. 先计算叶结点或终局结点的效用;
  2. MIN 层向上返回孩子中的最小值;
  3. MAX 层向上返回孩子中的最大值;
  4. 一直回传到根结点。

例:两层博弈树#

根结点 A 为 MAX,三个孩子 B、C、D 为 MIN。叶结点效用分别为:

B:{3,9,10}B:\{3,9,10\}C:{2,9,4}C:\{2,9,4\}D:{10,5,1}D:\{10,5,1\}

MIN 层先取最小值:

V(B)=min{3,9,10}=3V(B)=\min\{3,9,10\}=3V(C)=min{2,9,4}=2V(C)=\min\{2,9,4\}=2V(D)=min{10,5,1}=1V(D)=\min\{10,5,1\}=1

根结点 A 为 MAX:

V(A)=max{3,2,1}=3V(A)=\max\{3,2,1\}=3

因此 MAX 选择通向 B 的动作,并能在对手理性行动时保证得到 3。

配图占位:插入第 3 章 PPT 第 27—29 页的 Minimax 搜索树,建议保留 MAX / MIN 层标记与叶结点得分。

伪代码#

MinimaxValue(s):
if Terminal(s):
return U(s)
if Player(s) == MAX:
v ← -∞
for a in Actions(s):
v ← max(v, MinimaxValue(Result(s,a)))
return v
if Player(s) == MIN:
v ← +∞
for a in Actions(s):
v ← min(v, MinimaxValue(Result(s,a)))
return v

性质与复杂度#

若博弈树有限,并假设对手始终理性地采取最优策略,Minimax 能得到最优决策。

设平均分支因子为 bb,最大搜索深度为 mm

时间复杂度=O(bm)\text{时间复杂度}=O(b^m)

按深度优先方式实现时:

空间复杂度=O(bm)\text{空间复杂度}=O(bm)

Minimax 的主要问题是需要搜索大量结点,博弈树稍大就会发生组合爆炸。

Alpha-Beta 剪枝#

Alpha-Beta 剪枝在保持 Minimax 最终结果不变的前提下,删除不可能影响最终决策的分支。

α\alphaβ\beta 的含义#

  • α\alpha:沿当前搜索路径,MAX 已经能够保证获得的最好下界;
  • β\beta:沿当前搜索路径,MIN 目前允许 MAX 获得的最好上界。

初始时:

α=,β=+\alpha=-\infty,\qquad \beta=+\infty

在 MAX 结点,孩子返回价值 vv 后:

αmax(α,v)\alpha\leftarrow\max(\alpha,v)

在 MIN 结点,孩子返回价值 vv 后:

βmin(β,v)\beta\leftarrow\min(\beta,v)

若出现

αβ\boxed{\alpha\ge\beta}

则当前结点剩余尚未访问的孩子可以剪去。

为什么可以剪枝#

  • MAX 已经有一个至少为 α\alpha 的选择;
  • MIN 一旦发现当前分支最多只能返回 βα\beta\le\alpha
  • MAX 不会放弃已有的 α\alpha 去选择一个不超过它的分支;
  • 所以继续计算该分支的剩余孩子不会改变根结点决策。

例:剪去 x,yx,y#

考虑:

minimax(A)=max(min(3,9,10),min(2,x,y),min(10,5,1))\operatorname{minimax}(A) = \max\bigl( \min(3,9,10), \min(2,x,y), \min(10,5,1) \bigr)

先搜索第一棵子树:

min(3,9,10)=3\min(3,9,10)=3

因此根结点 MAX 已经有

α=3\alpha=3

再搜索第二棵 MIN 子树,看到第一个叶结点为 2:

min(2,x,y)2\min(2,x,y)\le2

无论 x,yx,y 是多少,该子树返回值都不会超过 2,而 MAX 已经能得到 3。因此 x,yx,y 对根结点选择没有影响,可以直接剪枝。

最后第三棵子树返回:

min(10,5,1)=1\min(10,5,1)=1

根结点仍为:

max(3,2,1)=3\max(3,\le2,1)=3

配图占位:插入第 3 章 PPT 第 29 页“alpha-beta 剪枝算法”,保留 min(2,x,y)\min(2,x,y) 与被剪去的两个分支。

Alpha-Beta 伪代码#

AlphaBeta(s, α, β):
if Terminal(s):
return U(s)
if Player(s) == MAX:
v ← -∞
for a in Actions(s):
v ← max(v, AlphaBeta(Result(s,a), α, β))
α ← max(α, v)
if α ≥ β:
break
return v
if Player(s) == MIN:
v ← +∞
for a in Actions(s):
v ← min(v, AlphaBeta(Result(s,a), α, β))
β ← min(β, v)
if α ≥ β:
break
return v

性质与复杂度#

  • 最终结果与完整 Minimax 相同;

  • 只减少搜索结点,不改变理论最优决策;

  • 最坏时间复杂度仍为

    O(bm)O(b^m)
  • 若优先搜索最有希望的动作,理想情况下可接近

    O(bm/2)O(b^{m/2})

这说明剪枝效果高度依赖结点访问顺序:越早找到好动作,α\alphaβ\beta 越快收紧,越容易剪掉后续分支。

配图占位:插入第 3 章 PPT 第 33 页“完整搜索树及 Alpha-Beta 剪枝过程”。建议保留每个结点的 [α,β][\alpha,\beta] 区间和叉号。


蒙特卡洛树搜索#

蒙特卡洛方法#

蒙特卡洛方法的基本思想是:

不一定先建立完整解析模型,而是通过大量随机试验和统计平均来估计结果。

抛硬币#

理论上公平硬币正反面概率各为 1/21/2。若只抛 10 次,频率可能偏离很大;若抛 1000 次、10000 次,正面频率通常会逐步接近 1/21/2

掷骰子#

对均匀六面骰子,大量重复试验后,每一面出现的频率趋近于 1/61/6

其理论基础是大数定律:样本数量足够大时,经验统计量会逐步接近真实期望。

蒙特卡洛树搜索(Monte Carlo Tree Search, MCTS)把这种随机采样思想用于搜索树:

  • 不完全展开整棵树;
  • 对部分分支进行多次模拟;
  • 用模拟结果估计结点价值;
  • 把更多计算资源分配给更有希望的分支。

多臂赌博机问题#

设智能体面前有 KK 台赌博机,每台有一个臂膀。每次选择一个臂膀后,会随机得到奖励。

  • ii 个动作:摇动第 ii 个臂膀;
  • ii 个臂膀的奖励分布:BiB_i
  • 奖励均值:μi\mu_i
  • tt 次选择的臂膀:ItI_t
  • 得到的奖励:XtBItX_t\sim B_{I_t}

算法不知道哪个 μi\mu_i 最大,只能一边尝试、一边调整策略。

经验平均奖励#

设到第 tt 轮为止,第 ii 个动作被选择 Ni(t)N_i(t) 次,其经验平均奖励为

Xˉi(t)=1Ni(t)j=1Ni(t)Xi,j\bar X_i(t) = \frac{1}{N_i(t)} \sum_{j=1}^{N_i(t)}X_{i,j}

regret:悔值函数#

设最优动作的期望奖励为

μ=maxiμi\mu^*=\max_i\mu_i

经过 TT 次操作,悔值可写为

RT=Tμt=1TXtR_T=T\mu^*-\sum_{t=1}^{T}X_t

它表示:

始终选择最优动作本来能获得的期望总收益,与智能体实际收益之间的差距。

算法的目标是让

E[RT]\mathbb E[R_T]

尽可能小。

贪心策略的不足#

最直接的策略是:

  1. 每个臂膀先尝试一次;
  2. 后续总是选择当前经验平均奖励最大的臂膀。

这就是贪心策略。

PPT 例子中有 5 台赌博机,其真实均值为

(μ1,μ2,μ3,μ4,μ5)=(0.3,0.4,0.5,0.6,0.7)(\mu_1,\mu_2,\mu_3,\mu_4,\mu_5) =(0.3,0.4,0.5,0.6,0.7)

真实最优动作是 5 号。

然而,在 10000 次模拟中,纯贪心算法可能因为初期随机结果较好而长期选择 4 号,甚至另一次运行中长期选择 2 号。

原因是:

  • 初期样本太少,平均值误差大;
  • 某个动作暂时领先后,算法不断选择它;
  • 其他动作几乎得不到新样本;
  • 错误估计无法被纠正;
  • 最终停留在“还不错但不是最好”的动作上。

这体现了 初值敏感性过早锁定 问题。

探索与利用#

exploitation:利用#

选择当前看来收益最高的动作,充分使用已经获得的经验。

exploration:探索#

尝试访问次数较少、真实潜力尚不明确的动作,以获得新信息。

只利用:可能长期困在次优动作。

只探索:无法充分利用已有经验,浪费大量机会。

因此,多臂赌博机和 MCTS 的关键都是:

在探索与利用之间取得平衡\boxed{\text{在探索与利用之间取得平衡}}

epsilon-贪心算法#

ε\varepsilon-贪心算法规定:

It={argmaxiXˉi(t1),以 1ε 的概率随机选择一个动作,以 ε 的概率I_t= \begin{cases} \displaystyle\arg\max_i\bar X_i(t-1), & \text{以 }1-\varepsilon\text{ 的概率}\\[8pt] \text{随机选择一个动作}, & \text{以 }\varepsilon\text{ 的概率} \end{cases}

含义:

  • 大部分时间利用当前最佳动作;
  • 少部分时间随机探索其他动作。

在 5 台赌博机例子中,引入探索后,算法有机会重新发现真实均值最高的 5 号臂膀。

局限#

  1. ε\varepsilon 应取多大缺少统一答案;
  2. 探索时完全随机,没有利用“不确定性大小”;
  3. 一个已经探索很多次且表现很差的动作,仍可能被随机选中;
  4. 访问极少、最值得获取信息的动作,没有得到更高优先级。

因此需要更有方向的探索策略。

UCB1 上置信区间算法#

UCB1(Upper Confidence Bound)为每个动作计算一个“乐观上界”:

UCBi(t)=Xˉi(t)+ClntNi(t)\boxed{ \operatorname{UCB}_i(t) = \bar X_i(t) + C\sqrt{\frac{\ln t}{N_i(t)}} }

PPT 中也写成等价形式

Xˉi(t)+c2lntNi(t)\bar X_i(t)+c\sqrt{\frac{2\ln t}{N_i(t)}}

常数因子可以吸收到超参数中。

算法选择:

It=argmaxiUCBi(t)I_t=\arg\max_i\operatorname{UCB}_i(t)

两部分的含义#

利用项#
Xˉi(t)\bar X_i(t)

历史平均奖励越高,动作越值得继续利用。

探索项#
ClntNi(t)C\sqrt{\frac{\ln t}{N_i(t)}}
  • Ni(t)N_i(t) 小:样本少,不确定性大,探索项大;
  • Ni(t)N_i(t) 大:估计较稳定,探索项变小;
  • tt 增大:算法仍保留缓慢增长的探索意愿;
  • CC 大:更偏向探索;
  • CC 小:更偏向利用。

UCB 的思想是 面对不确定性保持乐观

不只看当前平均值,还看这个动作在合理置信范围内可能达到多好。

配图占位:插入第 3 章 PPT 第 41 页“上限置信区间算法策略”,保留三个动作的均值、估计区间与置信上界。

Hoeffding 不等式带来的上界#

若奖励位于 [0,1][0,1],则经验均值满足 Hoeffding 不等式:

Pr(μiXˉi>δ)exp(2Niδ2)\Pr\left(\mu_i-\bar X_i>\delta\right) \le \exp\left(-2N_i\delta^2\right)

令右侧随时间快速减小,可以得到

δlntNi\delta\propto\sqrt{\frac{\ln t}{N_i}}

因此

Xˉi+ClntNi\bar X_i+C\sqrt{\frac{\ln t}{N_i}}

可以作为奖励均值的高概率上界。

PPT 给出的理论结论是,UCB1 的期望悔值随测试次数只按对数增长,其量级可写为

O(lnTΔ)O\left(\frac{\ln T}{\Delta}\right)

其中

Δ=minμi<μ(μμi)\Delta=\min_{\mu_i<\mu^*}(\mu^*-\mu_i)

表示最优动作与次优动作之间的最小均值差距。

从 UCB 到 UCT#

多臂赌博机是在多个独立动作间选择;树搜索是在父结点的多个孩子间选择。

把 UCB 推广到搜索树,得到 UCT(Upper Confidence Bounds for Trees):

UCT(vj)=Qˉ(vj)+ClnN(v)N(vj)\boxed{ \operatorname{UCT}(v_j) = \bar Q(v_j) + C\sqrt{\frac{\ln N(v)}{N(v_j)}} }

其中:

  • vv:父结点;
  • vjv_j:子结点;
  • N(v)N(v):父结点访问次数;
  • N(vj)N(v_j):子结点访问次数;
  • W(vj)W(v_j):子结点累计收益;
  • Qˉ(vj)=W(vj)/N(vj)\bar Q(v_j)=W(v_j)/N(v_j):子结点平均收益。

选择阶段总是进入 UCT 值最大的子结点。

  • 平均收益高的孩子得到利用;
  • 访问次数少的孩子得到探索;
  • 未访问孩子通常令 UCT 为 ++\infty,保证至少被尝试一次。

MCTS 的四个阶段#

一次完整的蒙特卡洛树搜索迭代包含四步。

1. selection:选择#

从根结点出发,在已经建立的搜索树中反复选择 UCT 值最大的孩子,直到:

  • 到达终局结点;或
  • 到达尚未完全展开的结点。

2. expansion:扩展#

若当前结点不是终局,并且仍有合法动作未生成,则选择一个未尝试动作,生成一个新子结点。

扩展的含义是:在当前搜索树边界上打开一个新分支。

3. simulation / rollout:模拟#

从新结点出发,使用较简单的策略继续行动,直到:

  • 到达终局;或
  • 到达预设截断深度,再用估值函数评价。

基础 MCTS 常使用随机策略。

若终局收益记为 zz,二人零和博弈中可取:

z{1,0,1}z\in\{1,0,-1\}

分别表示胜、平、负。

4. backpropagation:回传#

将模拟得到的 zz 沿本轮访问路径向上回传,更新:

N(v)N(v)+1N(v)\leftarrow N(v)+1W(v)W(v)+zW(v)\leftarrow W(v)+zQˉ(v)=W(v)N(v)\bar Q(v)=\frac{W(v)}{N(v)}
NOTE

这里的“反向传播”指把模拟结果沿搜索路径回传并更新统计量,与神经网络训练中的梯度反向传播含义不同。

配图占位:插入第 3 章 PPT 第 45 页“MCTS 的选择—扩展—模拟—反向传播四阶段示意图”。

例:一次完整的 UCT 迭代#

课程 PPT 中结点写成

累计收益访问次数\frac{\text{累计收益}}{\text{访问次数}}

初始树中:

  • 根结点:15/2-15/2
  • 左孩子 L:10/110/1
  • 右孩子:5/15/1

选择#

父结点访问次数为 2。按 PPT 使用的 UCB 形式:

UCB(L)=101+2ln2111.18\operatorname{UCB}(L) = \frac{10}{1}+\sqrt{\frac{2\ln 2}{1}} \approx 11.18UCB(R)=51+2ln216.18\operatorname{UCB}(R) = \frac{5}{1}+\sqrt{\frac{2\ln 2}{1}} \approx 6.18

因此选择左孩子 L。

扩展#

L 仍有未扩展动作,随机生成新孩子 C:

C:0/0C:0/0

其他尚未扩展的孩子可将 UCB 视为 ++\infty,确保后续有机会被探索。

模拟#

从 C 出发采用随机策略模拟到终局,得到终局得分:

z=3z=3

回传#

PPT 为了让所有层都能统一使用“选择最大 UCB”的规则,采用交替符号的记分约定:

  • MIN 层结点累计收益加 zz
  • MAX 层结点累计收益减 zz

于是更新为:

C:0/03/1C:0/0\rightarrow -3/1L:10/113/2L:10/1\rightarrow 13/2root:15/218/3\text{root}:-15/2\rightarrow -18/3

一次迭代结束后,所有经过结点的访问次数和累计收益都被更新,下一轮再重新计算 UCT。

配图占位:插入第 3 章 PPT 第 46—47 页“蒙特卡洛树搜索一次迭代”。需保留四幅子图 (a)—(d) 与 15/2,10/1,5/1,3/1,13/2,18/3-15/2,10/1,5/1,-3/1,13/2,-18/3

TIP

收益视角有多种等价实现方式:

  1. 始终从根玩家视角记录同一个 zz
  2. 按当前行动方视角记录,并在相邻层之间翻转符号;
  3. 像课程 PPT 一样,通过给不同层累计相反符号,使各层都能统一做 argmax

关键是全程使用同一种约定。

MCTS 的整体流程#

输入:根结点 root,计算预算 Budget
for iter = 1 ... Budget:
node ← root
# 1. 选择
while node 非终局且已完全展开:
node ← UCT 最大的子结点
# 2. 扩展
if node 非终局且尚未完全展开:
从未尝试动作中选择一个动作
node ← 新生成的子结点
# 3. 模拟
z ← 从 node 出发快速模拟得到的收益
# 4. 回传
沿访问路径向根结点回传 z
更新每个结点的 N、W、Q
输出:根结点下访问次数最多或统计结果最稳定的动作

MCTS 的特点#

  1. 按预算工作:计算时间越多,采样越多,统计通常越稳定;
  2. 不要求完整展开搜索树
  3. 适合分支因子很大的问题
  4. 基础版不强依赖精确启发函数
  5. 有限预算下通常得到近似最优解
  6. 可以与策略模型、价值模型和领域知识结合

与 Minimax 的区别#

对比项Minimax / Alpha-BetaMCTS / UCT
基本思想递归推理并回传精确或静态估值随机模拟并统计估值
树的展开尽可能系统展开选择性、逐步生长
结点选择MAX / MIN 规则UCT 平衡探索与利用
结果性质搜索范围内的确定性最优有限预算下的近似决策
适合场景分支较可控、估值函数较强分支巨大、难以穷举
时间增加后的效果可以搜索得更深样本增多,统计更稳

可以用一句话概括:

Minimax 尽量把树“算清楚”;MCTS 通过不断试探把树“估准一些”。

组合爆炸与地平线问题#

组合爆炸#

PPT 以国际象棋中的香农数说明搜索规模:

  • 第一次移动约有 20 种可能;
  • 两步组合约有 400 种;
  • 搜索到更深层后,可能局面迅速达到上亿;
  • 完整博弈树规模可估计到约 1012010^{120} 量级。

因此不可能把所有可能局面全部展开。

应对思路主要有:

  • 剪枝:证明某些分支不可能影响结果,直接放弃,如 Alpha-Beta;
  • 采样:只模拟部分分支,用统计结果近似估值,如 MCTS。

horizon problem:地平线问题#

若搜索只能看到有限深度,某个动作的真正后果可能发生在搜索深度之外。

算法在当前“地平线”以内看起来判断合理,却可能忽略更远处的关键变化。

PPT 用 AlphaGo 与李世石第四局的关键落子说明这一现象。这里应把它理解为有限搜索深度和估值能力可能遗漏远期后果的概念示例。

配图占位:插入第 3 章 PPT 第 50 页“组合爆炸与地平线问题”。


本章总结#

算法选择表#

问题特征优先考虑的方法原因
不掌握额外信息,只需系统遍历深度优先 / 广度优先结构简单,不依赖启发函数
希望尽快找到可行解贪婪最佳优先搜索直接朝估计目标方向推进
希望寻找代价最小路径A*同时考虑 g(n)g(n)h(n)h(n)
两名理性对手轮流博弈Minimax显式模拟 MAX 与 MIN 的最优响应
Minimax 搜索树过大Alpha-Beta不改变结果地剪去无效分支
搜索树巨大,无法穷举MCTS / UCT用采样与统计分配计算资源

易混淆点#

1. 状态与结点#

  • 状态只描述当前情形;
  • 结点还记录到达路径;
  • 多个结点可以对应同一个状态。

2. OPEN 与当前结点的孩子#

OPEN 包含全部尚未扩展候选结点,不只包含刚生成的孩子。

3. 目标测试与最优性#

到达目标只说明找到一个解;能否立即停止,要看算法是否保证第一个解最优。

4. g(n)g(n)h(n)h(n)f(n)f(n)#

  • g(n)g(n):已经付出的真实代价;
  • h(n)h(n):未来剩余代价的估计;
  • f(n)f(n):决定下一个扩展谁。

5. 可容性与一致性#

一致性可容性\text{一致性}\Rightarrow\text{可容性}

一致性更强。

6. Minimax 与 Alpha-Beta#

Alpha-Beta 只减少搜索量,最终结果与 Minimax 相同。

7. 贪心与 ε\varepsilon-贪心#

  • 贪心:只利用;
  • ε\varepsilon-贪心:大部分利用,小概率随机探索。

8. UCB 的两个部分#

UCB=历史平均收益+不确定性奖励\text{UCB}=\text{历史平均收益}+\text{不确定性奖励}

9. MCTS 的回传#

更新的是访问次数、累计收益和平均收益;若使用当前玩家视角,要注意相邻层符号翻转。

复习清单#

本章至少应能做到:

  • 写出搜索问题的六个基本要素;
  • 解释状态、结点、路径、OPEN、CLOSED 与扩展;
  • 根据 OPEN 表手工演示一次搜索过程;
  • 说清完备性、最优性、时间复杂度与空间复杂度;
  • 区分启发函数 h(n)h(n) 与评价函数 f(n)f(n)
  • 用城市 A 到 K 的例子演示贪婪搜索与 A*;
  • 写出并解释 f(n)=g(n)+h(n)f(n)=g(n)+h(n)
  • 判断一个启发函数是否可容、一致;
  • 按 MAX / MIN 层从叶结点向上计算 Minimax 值;
  • 使用 α\alphaβ\beta 判断哪些分支可以剪枝;
  • 解释纯贪心策略为什么可能锁定次优臂膀;
  • 写出 ε\varepsilon-贪心与 UCB1 的动作选择规则;
  • 解释 UCB 中均值项与探索项的作用;
  • 按“选择—扩展—模拟—回传”说明一次 MCTS 迭代;
  • 解释剪枝与采样如何缓解组合爆炸。
OceanAI-Chpater3:搜索探寻与问题求解
https://www.sleepyfish2031.top/posts/课程笔记/海洋人工智能基础/chapter3/
作者
Sleepyfish
发布于
2026-06-13
许可协议
CC BY-NC-SA 4.0