1.3 无信息搜索(Uninformed Search)
1. 无信息搜索的基本框架:树搜索
无信息搜索的目标是从起始状态找到目标状态的计划(路径)。标准方法是基于搜索树,通过维护一个前沿 (Frontier) 来探索状态空间:
-
前沿:包含部分计划(从起始状态到某些状态的路径)的节点集合。
-
过程:
-
从前沿中根据某种策略选择一个节点(对应一个长度为 ( n ) 的部分计划)。
-
将该节点移除,并用其所有子节点(长度为 ( n+1 ) 的计划)替换回前沿。
-
重复此过程,直到从前沿中移除一个目标状态,此时该状态对应的路径是从起始状态到目标状态的解。
-
树搜索伪代码
function TREE-SEARCH(problem, frontier) return a solution or failure frontier ← INSERT(MAKE-NODE(INITIAL-STATE[problem]), frontier) while not IS-EMPTY(frontier) do node ← POP(frontier) if problem.IS-GOAL(node.STATE) then return node for each child-node in EXPAND(problem, node) do add child-node to frontier return failure function EXPAND(problem, node) yields nodes s ← node.STATE for each action in problem.ACTIONS(s) do s' ← problem.RESULT(s, action) yield NODE(STATE=s', PARENT=node, ACTION=action)
-
初始化:将起始状态节点插入前沿。
-
循环:
-
从前沿弹出一个节点(
POP
的策略取决于具体搜索方法)。 -
检查是否为目标状态,若是则返回。
-
用
EXPAND
生成所有子节点,加入前沿。
-
-
EXPAND:根据动作集和转移模型生成子节点,记录状态、父节点和动作。
节点信息
实际实现中,节点通常包含:
-
状态:当前状态。
-
父节点:追溯路径用。
-
距离/成本:从起始状态到当前状态的代价。
无信息搜索
当我们不知道目标状态的位置时,使用无信息搜索 (Uninformed Search),依赖预定策略扩展节点。以下介绍三种策略:深度优先搜索 (DFS)、广度优先搜索 (BFS) 和 均匀代价搜索 (UCS)。
2. 属性分析的维度
评估搜索策略时,我们关注以下属性:
-
完备性 (Completeness):如果存在解,策略是否保证找到它(假设无限计算资源)?
-
最优性 (Optimality):策略是否保证找到代价最小的路径?
-
分支因子 ( b ):每个节点平均生成 ( b ) 个子节点,深度 ( k ) 有 ( O(b^k) ) 个节点。
-
最大深度 ( m ):搜索树可能的最大深度。
-
最浅解深度 ( s ):最浅目标状态的深度。
3. 深度优先搜索 (Depth-First Search, DFS)
(1) 描述
-
策略:总是选择前沿中最深的节点(离起始状态最远的)进行扩展。
-
行为:沿着一条路径深入,直到无法继续(无子节点或找到目标),然后回溯。
(2) 前沿表示
-
需求:每次移除最深节点,其子节点成为新的最深节点,需要优先处理最近添加的节点。
-
实现:使用后进先出 (LIFO) 栈,新节点入栈后立即成为下一个处理的节点。
(3) 属性
-
完备性:
-
不完备。如果状态空间图有循环,搜索树可能无限深,DFS 会陷入无限探索而找不到解。
-
示例:在一个有环的迷宫中,DFS 可能沿着环无限走下去。
-
-
最优性:
-
不最优。DFS 找到的是搜索树中最左边的解,不考虑路径成本。
-
示例:可能找到一条长路径而忽略更短的路径。
-
-
时间复杂度:
-
最坏情况:探索整个搜索树,最大深度为 ( m ),节点数为 ( O(b^m) )。
-
-
空间复杂度:
-
最坏情况:前沿保存 ( m ) 层每层最多 ( b ) 个节点,总共 ( O(bm) )。
-
原因:DFS 一次只深入一个子树,其他兄弟节点暂存。
-
(4) 示例
-
在迷宫中,DFS 从起点一直向右走,直到撞墙或找到出口,然后回溯尝试其他方向。
4. 广度优先搜索 (Breadth-First Search, BFS)
(1) 描述
-
策略:总是选择前沿中最浅的节点(离起始状态最近的)进行扩展。
-
行为:按层级逐层探索,先处理所有深度 1 的节点,再处理深度 2 的节点,依此类推。
(2) 前沿表示
-
需求:按插入顺序处理节点,优先扩展最早加入的节点。
-
实现:使用先进先出 (FIFO) 队列,保证浅层节点先被处理。
(3) 属性
-
完备性:
-
完备。如果存在解,其最浅深度 ( s ) 是有限的,BFS 最终会搜索到该深度。
-
-
最优性:
-
一般不最优。不考虑路径成本,只找最浅的解。
-
特例:如果所有边的成本相等,BFS 等价于均匀代价搜索,此时最优。
-
-
时间复杂度:
-
最坏情况:探索到最浅解深度 ( s ),总节点数为 ( 1 + b + b^2 + ... + b^s = O(b^s) )。
-
-
空间复杂度:
-
最坏情况:前沿包含深度 ( s ) 的所有节点,即 ( O(b^s) )。
-
原因:BFS 同时保存一层的所有节点。
-
(4) 示例
-
在迷宫中,BFS 从起点向四周扩散,先检查所有一步可达的位置,再检查两步可达的位置,直到找到出口。
5. 均匀代价搜索 (Uniform Cost Search, UCS)
(1) 描述
-
策略:总是选择前沿中路径成本最低的节点进行扩展。
-
行为:按从起始状态到当前状态的总成本排序,逐步扩展成本最低的路径。
(2) 前沿表示
-
需求:按路径成本从小到大排序。
-
实现:使用基于堆的优先级队列,优先级为从起始状态到节点的后向成本 (Backward Cost)。
(3) 属性
-
完备性:
-
完备。如果存在目标状态,其最短路径成本有限,UCS 最终会找到。
-
-
最优性:
-
最优(前提:所有边成本非负)。因按成本递增顺序扩展,第一个找到的目标状态必是最优路径。
-
与 Dijkstra 算法类似,但 UCS 在找到目标时终止。
-
注意:若边成本可为负,可能破坏最优性(需用 Bellman-Ford 算法)。
-
-
时间复杂度:
-
定义 ( C^* ) 为最优路径成本,( \epsilon ) 为最小边成本。
-
最坏情况:探索成本小于 ( C^* ) 的所有节点,深度上限约为 ( \frac{C^*}{\epsilon} ),复杂度为 ( O(b^{C^*/\epsilon}) )。
-
-
空间复杂度:
-
前沿包含最优解层级的节点,约为 ( O(b^{C^*/\epsilon}) )。
-
(4) 示例
-
在迷宫中,UCS 优先扩展总步数最少的路径(假设每步成本为 1),保证找到最短路径。
6. 三种策略对比
策略 | 前沿表示 | 完备性 | 最优性 | 时间复杂度 | 空间复杂度 |
---|---|---|---|---|---|
DFS | LIFO 栈 | 否 | 否 | ( O(b^m) ) | ( O(bm) ) |
BFS | FIFO 队列 | 是 | 否(特例是) | ( O(b^s) ) | ( O(b^s) ) |
UCS | 优先级队列 | 是 | 是(非负成本) | ( O(b^{C^*/\epsilon}) ) | ( O(b^{C^*/\epsilon}) ) |
-
DFS:深入探索,空间效率高,但可能陷入死循环。
-
BFS:按层扩散,保证找到最浅解,但空间需求大。
-
UCS:按成本优化,保证最优解,但计算开销可能更高。
7. 总结与核心要点
-
树搜索框架:通过前沿扩展搜索树,找到从起始状态到目标状态的路径。
-
无信息搜索:不依赖目标位置信息,仅靠策略选择扩展顺序。
-
三种策略:
-
DFS:最深优先,栈实现,适合空间受限但不完备。
-
BFS:最浅优先,队列实现,完备但非最优。
-
UCS:成本最低优先,优先级队列实现,完备且最优(非负成本)。
-
-
共同点:都基于树搜索框架,仅扩展策略不同。