Puzzle问题
本章以Puzzle问题为例,对搜索策略进行分析
深度优先与广度优先
最坏时间复杂度(可行解在树的右下角) | 最坏空间复杂度(可行解在树的右下角) | |
---|---|---|
深度优先搜索 | θ(ωh) | (h-1)(ω-1) |
广度优先搜索 | θ(ωh) | ωh-1 |
- ω为每个节点的子节点数,h为树的深度
- 一般用深度找可行解或可行解在左下角,用广度找最优解或可行解在中间层
- 深度使用的数据结构是栈(保存了搜索路径上的节点信息),广度使用的数据结构是队列(只需要保存当前层的所有节点,而不需要保存所有已访问过的节点的状态信息),数据结构决定了二者的最坏空间复杂度
搜索的优化
爬山法
来源:在深度优先搜索过程中,我们经常遇到多个节点可以扩展的情况,首先扩展哪个比较好?
基本思路:爬山策略使用贪心方法确定搜索的方向,是优化的深度优先搜索策略(使用启发式测度来排序节点扩展的顺序)
数据结构:栈
Best-First搜索策略
基本思路:结合深度和广度的优点(深度的空间节省、广度的横向比较)
数据结构:堆
分支界限
基本思想:先发现优化解的一个界限,再利用界限缩小解空间, 提高求解的效率
具体步骤
- 使用分支来表示问题的解,即确定分支划分的方法
- 通过爬山法或Best-First找到解的界限
- 进行分支界限搜索,即利用找到的界限剪除不可能产生优化解的分支
技巧
- 建立分支的时候选择能能使树变瘦长的分支方法
问题示例
人员安排问题
必要知识点——拓扑排序
输入:偏序集合(S, ≤)
输出::S的拓朴序列是<s1, s2, …, sn>,满足: 如果si≤sj, 则si排在sj的前面
确定划分方法
拓扑算法生成解空间
- 问题的解空间是所有拓朴排序的序列集合,每个序列对应一个可能的解
- 问题的树表示(即用树表示所有拓朴排序序列)
- 代价矩阵“减0”操作
通过爬山法找到解的界限
爬山法得到可行解及上界
利用找到的界限剪除不可能产生优化解的分支
分支界限得到最优解
旅行商问题
输入:连通图G=(V, E),每个节点都没有到自身的边,每对节点之间都有一条非负加权边
输出:一条由任意一个节点开始,经过每个节点一次,最后返回开始节点的路径,该路径的代价(即权值之和)最小
确定划分方法
- 所有解集合作为树根
- 树的划分过程:
- 所有包含(i, j)的解集合作为左子树,所有不包含(i, j)的解集合作为右子树((i, j)的选择策略:选择图上边(i, j)使右子树代价下界增加最大)
- 计算出左右子树的代价下界
- 构造根节点
- 处理技巧1:优化代价矩阵
- 处理技巧1:优化代价矩阵
- 划分过程
通过爬山法找到解的界限
- 从代价下界小的一边进行递归分支,直到找到一个解,这个解的代价实际就是优化解的上界α
- 递归分支
- 做出新的代价矩阵(左子树)
- 做出新的代价矩阵(右子树)
- 做出新的树
- 爬山策略扩展左子树根
- 做出新的代价矩阵(左子树)
利用找到的界限剪除不可能产生优化解的分支
- 从未扩展的节点开始继续扩展,如果一个节点的代价下界超过α, 则终止该节点的扩展
- 反复递归后得到
- 通过解“1-5-6-7-3-5-2-1”得到优化解的上界为126,再看未扩展的节点,未扩展的节点中代价下界最小的是128,而128>126,不需要扩展(剪除),得到“1-5-6-7-3-5-2-1”即为最优解
A*算法
- 分支界限策略是为了剪掉不能达到优化解的分支,其关键是“界限”
- A*算法的核心是告诉我们在某些情况下, 我们得到的解一定是优化解, 于是算法可以停止
- A*算法试图尽早地发现优化解
- A*算法经常使用Best-first策略求解优化问题
正确性证明
- 我们先定义一些名词:
当我们到达点n时,已经付出的代价为g(n),这是我们已经知道的
然后假设有上帝,告诉我们从点n到终点t的最优解为h*(n)
但是没有上帝,我们仅仅用n点下一步路径的最短值h(n)估计值h(n)
设f(n)=g(n)+h(n)、f(n)=g(n)+h*(n),显然f(n)≤f*(n)
f(n)是我们实际计算得到,并加入堆中进行Best-First比较的
每次会有很多个可扩展的点(可扩展的点都称为点n),A*算法就是将这些可扩展的点加入堆中比较,找到最小的f(n’),然后再对n’进行扩展,扩展之后将点n’出堆,并将扩展后多出的可扩展的点再加入堆中进行比较,如此递归扩展,直到开始**对终点t进行扩展为止(不是扩展到终点t,而是开始对终点t进行扩展。扩展到终点t是指将t加入堆,开始对终点t进行扩展是指此时堆中 f(t)最小),这时f(t)=g(t)即为最优解 - 然后我们来证明正确性,即证通过不断对较小的f(n)对应的点n进行扩展,扩展到终点t后得到的g(t)为最优解
- f(t)≤f(n),n是任意可拓展的点,t是终点
- 进而因为f(n)≤f*(n),有f(t)≤f*(n)
- 当前所有可扩展的点n里面一定有一个是最优解,设它为s,那么根据c.有f(t)≤f*(s)
- 由于t是目标节点,进而h(t)=0,所以有f(t)=g(t)+h(t)=g(t)≤f*(s)
- f(t)=g(t)为一个可行解,而f*(s)为一个最优解,所以f(t)=g(t)≥f*(s),再由d.得f(t)=g(t)=f*(s),即g(t)为最优解
例子
如果你喜欢这篇文章,别忘了点点赞和收藏🥰
更多内容及实时更新请访问笔者语雀知识库,本篇内容可在第8章 搜索策略查看(打开文档后点击右上角演示可获得更好的阅读效果哦~)