回溯法
1、回溯法概述
- 回溯法可以系统的搜索一个问题的所有解或任一个解
- 它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。算法搜索到某一结点时,如果断定该结点肯定不包含问题的解,则跳过以该结点为根的子树的搜索,逐层向其祖先结点回溯
- 这种以深度优先方式搜索问题的解的方法称为回溯法
2、回溯法思想
- 第一步:为问题定义一个状态空间(state space),这个空间必须至少包含问题的一个解
- 第二步:组织状态空间以便它能被容易地搜索。典型的组织方法是图或树
- 第三步:按深度优先的方法从开始结点进行搜索
- 开始结点是一个活结点(也是E-结点:expansion node)
- 如果能从当前的E-结点移动到一个新结点,那么这个新结点将变成一个活结点和新的E-结点,旧的E-结点仍是一个活结点。
- 如果不能移到一个新结点,当前的E-结点就“死”了(即不再是一个活结点),那么便只能返回到最近被考察的活结点(回溯),这个活结点变成了新的E-结点。
- 当我们已经找到了答案或者回溯尽了所有的活结点时,搜索过程结束。
3、回溯法如何提高效率?
- 由开始结点到当前E-结点构成解向量(x1,…,xi)
- 如果判定(x1,…,xi)不能导致最优解,那么就将可能要测试的mi+1…mn个向量略去。
因此回溯法的测试次数比硬性处理作的测试次数要少得多。
回溯法的解需要满足一组综合的约束条件,通常分为:显式约束和隐式约束,显式约束条件限定每个xi只从一个给定的集合上取值,隐式约束描述了xi必须彼此相关的情况,如0/1背包问题中的背包重量M
4、回溯算法的形式描述
假设回溯算法要找出所有的答案结点而不是仅仅只找出一个。
设(x1,x2,…,xi-1)是状态空间树中由根到一个结点(问题状态)的路径。
② T(x1,x2,…,xi-1)是下述所有结点的xi的集合,它使得对于每一个xi,(x1,x2,…,xi)是一条由根到结点xi的路径
③ 存在一些限界函数Bi(可以表示成一些谓词),如果路径(x1,x2,…,xi)不可能延伸到一个答案结点,则Bi(x1,x2,…,xi)取假值,否则取真值。
因此,解向量X(1:n)中的第i个分量就是那些选自集合T(x1,x2,…,xi-1)且使Bi为真的xi。
procedure BACKTRACK(n) integer k, n; local X(1:n) k←1 while k>0 do if 还剩有没检验过的X(k)使得 X(k) ∈T(X(1),…X(k-1)) and B(X(1),…X(k))=true then if(X(1),…,X(k)) 是一条已抵达一答案结点的路径 then print(X(1),…,X(k)) endif k ←k+1 else k ←k-1 endif repeat end BACKTRACK |
5、效率分析应考虑的因素
(1)生成下一个X(k)的时间
(2)满足显式约束条件的X(k)的数目
(3)限界函数Bi的计算时间
(4)对于所有的i,满足Bi的X(k)的数目
6、应用
8-皇后问题
子集和数问题
图的着色问题
哈密顿环
背包问题