分治算法、动态规划、贪心算法和回溯算法这些策略都是思想,它们有自己适合的问题域,回溯算法适合的问题:解是向量的形式,这个过程中不断的扩张向量,并且做跳跃式的遍历,中间需要做回溯判定,同时要对约束条件作判定,以下对回溯算法的设计思想和适用条件进行总结。
文章目录
一、问题分析
问题 | 解性质 | 解描述向量 | 搜索空间 | 搜索方式 | 约束条件 |
---|---|---|---|---|---|
n后 | 可行解 | < x 1 , x 2 , … , x n > , x i : 第 i 行 列 号 <x_1, x_2,…,x_n>,x_i:第i行列号 <x1,x2,…,xn>,xi:第i行列号 | n叉树 | 深度,宽度优先 | 彼此不攻击 |
0-1背包 | 最优解 | < x 1 , x 2 , … , x n > , x i = 0 , 1 , x i = 1 ⇔ 选 i <x_1, x_2,…,x_n>,x_i = 0,1,x_i=1⇔选i <x1,x2,…,xn>,xi=0,1,xi=1⇔选i | 子集树 | 深度,宽度优先 | 不超背包重量 |
货郎 | 最优解 | < i 1 = 1 , i 2 , … , i n > , 1 , 2 , … , n 的 排 列 < i_1=1, i_2,…,i_n>,1,2,…,n的排列 <i1=1,i2,…,in>,1,2,…,n的排列 | 排列树 | 深度,宽度优先 | 选没有经过的城市 |
特点 | 搜索解 | 向量,不断扩张部分向量 | 树 | 跳跃式遍历 | 约束条件回溯判定 |
二、深度与宽度优先搜索
1、深度优先访问顺序:
1→2→3→5→8→9→6→7→4
2、宽度优先访问顺序:
1→2→3→4→5→6 →7→8→9
三、回溯算法基本思想
回溯算法适合求解优化问题,很多问题都可以转化为优化问题来做,而优化问题又可以用现代的智能优化算法,或者使用机器学习的算法求一个近似解。
1、适用:
求解搜索问题和优化问题
2、搜索空间:
树,结点对应部分解向量,可行解在树叶上
3、 搜索过程:
采用系统的方法隐含遍历搜索树
4、搜索策略:
深度优先,宽度优先,函数优先,宽深结合等
5、结点分支判定条件:
满足约束条件—分支扩张解向量
不满足约束条件,回溯到该结点的父结点
6、 结点状态:
动态生成白结点(尚未访问)
灰结点(正在访问该结点为根的子树)
黑结点(该结点为根的子树遍历完成)
7、存储:
当前路径
三、结点状态
在遍历的时候,比如皇后问题里面的摆放,访问的次序,已经访问的,访问结束的,还没有访问的,有不同的颜色。
1、深度优先访问次序:
1→2→3→5→8
2、已完成访问:
2, 8
3、已访问但未结束:
1, 3, 5
4、尚未访问:
9, 6, 7, 4
四、回溯算法的适用条件
回溯算法的条件是部分向量和整体向量之间的关系,比如皇后问题,前面摆放皇后的时候产生了冲突,其实在往后扩张向量是没有意义的,这样的叫做多米诺性质,也就是说向量已经不满足条件了,以皇后问题理解,就是前面的k个皇后已经产生冲突了,下面没有必要在继续做了;如果前面k个物品装入背包已经超过物品的总重量了,那就是打破约束条件不满足了,接下来再往背包里装物品也没有必要了。
1、适用条件
在结点 < x 1 , x 2 , . . . , x k > 处 <x_1,x_2,...,x_k>处 <x1,x2,...,xk>处 P ( x 1 , x 2 , … , x k ) 为 真 P(x_1, x_2, …, x_k)为真 P(x1,x2,…,xk)为真
⇔ 向 量 < x 1 , x 2 , … , x k > 向量<x_1, x_2, …, x_k > 向量<x1,x2,…,xk>满足某个性质
(n后中k个皇后放在彼此不攻击的位置)
2、多米诺性质:
P ( x 1 , x 2 , … , x k + 1 ) → P ( x 1 , x 2 , … , x k ) 0 < k < n P(x_1,x_2,…,x_k+1)→P(x_1,x_2,…,x_k) 0<k<n P(x1,x2,…,xk+1)→P(x1,x2,…,xk)0<k<n
¬ P ( x 1 , x 2 , … , x k ) → ¬ P ( x 1 , x 2 , … , x k + 1 ) 0 < k < n k 维 向 量 不 满 足 约 束 条 件 , 扩 张 向 量 到 k + 1 维 仍 旧 不 满 足 , 可 以 回 溯 ¬P(x1,x2,…,xk)→¬P(x1,x2,…,xk+1) 0<k<n k 维向量不满足约束条件,扩张向量到 k+1维仍旧不满足,可以回溯 ¬P(x1,x2,…,xk)→¬P(x1,x2,…,xk+1)0<k<nk维向量不满足约束条件,扩张向量到k+1维仍旧不满足,可以回溯