第五章 回溯法--基本概念--n后问题
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
遍历子集树的任何算法均需Ω(2n)的计算时间。
第五章 回溯法 10
用回溯法搜索子集树的一般算法可描述如下:
void Backtrack(int t)
{ if (t > n) Output(x);
else for (int i=0; i<=1; i++)
{ x[t]=i;
if (Constraint(t) && (Bound(t))
第五章 回溯法 1
一、回溯法的算法框架
1. 问题的解空间 应用回溯法解问题时,首先应明确定义问题的解空 间。问题的解空间应至少包含问题的一个(最优)解。 例: 对于有n种可选物品的0-1背包问题,其解空间由长 度为n的0-1向量组成。该解空间包含了对变量的所有 可能的0-1赋值。当n=3时,其解空间是:
} }
注意:在调用Backtrack(1)执行此回溯算法之前, 先将变量数组x初始化为单位排列(1,2,…,n)。
第五章 回溯法 13
二、n后问题 (p154)
1. 问题描述
n后问题要求在一个n*n格的棋盘上放置n个皇后,使 得她们彼此不受攻击。一个皇后可以攻击与之在同一行或 同一斜线上的其他任何棋子。因此,n后问题等价于: 任何两个皇后不能在同行、同列、同一斜线上。
0 1
E
0 1
F
0 1
G
0
I
J
K
L
M
N
O
图5-1 0-1背包问题的解空间树
第五章 回溯法 3
例: n=3时的0-1背包问题,W={16,15,15}, p={45,25,25},C=30。在其解空间树上搜索最 优解的过程如下图所示。
1 B A
0 1
C 0 G 0 1 N
25
1
D
0
E
F 0
K
45
1
H
void Backtrack(int t)
{ if (t > n) Output(x); else for (int i=t; i<=n; i++)
{ Swap(x[t],x[i]);
if (Constraint(t) && (Bound(t)) Backtrack(t+1));
Swap(x[t],x[i]);
{(0,0,0), (0,1,0), (0,0,1), (1,0,0), (0,1,1), (1,0,1), (1,1,0), (1,1,1)}
第五章 回溯法 2
通常把解空间组织成解空间树或图。例如:对于 n=3时的0-1背包问题,其解空间用一棵完全二叉 树表示,如下图所示。
1
A
0
B
1
0
C
1
0
D 1 H
87
1 2 3 4
172
257
88 109 130
4 77 4 76 1
151
╳ ╳
2 3 72
╳
╳
73
82
152 1 2 3 4
1 2 3 74 75
153 154 155 156
四后问题的解空间树
有2个可行解:
15 回溯法 (2,第五章 4, 1 ,3)、(3,1,4,2)
2. 算法设计
对n后问题,可用n元组x[1:n]表示它的解。 其中,x[i]表示皇后i放在棋盘的第i行的第x[i] 列。 若2个皇后放置的位置分别是(i,j)和(k,l),则 约束条件为: x[i]≠x[k] (不在同一列) i+j≠k+l, i-k≠j-l (不在同一斜线) 即|i- k|≠|j- l| 用回溯法解n后问题时,可以用一棵完全n叉树 来表示其解空间。用可行性约束函数Place可剪 去不满足行、列和斜线约束的子树。
n后问题的回溯算法
第五章 回溯法 5
例:旅行售货员问题:某售货员要到若干城市推销商 品,已知各城市间的路程(或旅费)。他要选一条从 驻地出发,经过每个城市一遍,最后回到驻地的路线, 使总的路程(总的旅费)最小。
1 6 4 3 20 4 3 30 5 A A 2 10 2 1
B
3 4
C
4 G G 3 M M 2 H H 4 N N
D D
4 26>25 2 I I 3 P P 2 J J
E
3
图5-3 四个顶点的带权图
F
4 LLeabharlann BaiduL 59
K
2 Q Q
O
60+6>59 25
第五章 回溯法
19+6=25 29+30>25
6
图5-4 旅行售货员问题的可行解空间树
综上所述,回溯法解题包含以下步骤:
(1) 针对所给的问题,定义问题的解空间;
Backtrack(t+1));
}
}
第五章 回溯法 11
当所给的问题确定n个元素满足某种性质的排 列时,相应的解空间树称为排列树。
例如,旅行售货员问题相应的解空间树称为排 列树。排列树通常有n!个叶结点。遍历子集 树的任何算法均需Ω(n!)的计算时间。
第五章 回溯法
12
用回溯法搜索排列树的一般算法可描述如下:
if (Constrain(t) && Bound (t)) Backtrack(t+1); }
}
第五章 回溯法 8
用回溯法解题的一个显著特征:
问题的解空间是在搜索过程中动态生成的。 在任何时刻,算法只保存从根结点到当前扩展 结点的路径。若解空间树中从根到叶的最长路 径长度为h(n),则回溯法所需的计算空间通 常为O(h(n))。显式存储整个解空间则需要 O(2 h(n))。
(2) 确定易于搜索的解空间结构—解空间树;
(3) 以深度优先的方式搜索解空间树,并在搜索 过程中用剪枝函数(约束函数或限界函数) 避免无效搜索。
第五章 回溯法
7
3. 递归回溯
由于回溯法是对解空间的深度优先搜索,因此,一 般可用递归函数实现回溯法如下:
void Backtack(int t) { if ( t > n ) Output(x); //t表示递归深度 else for (int i = f(n,t); i<=g(n,t); i++) // f(n,t),g(n,t):分别表示当前可扩展结点未搜索过的 子树的起始编号和终止编号. { x[t] =h(i); //h(i ):在当前扩展结点处x[t]的第i个可取值
第五章 回溯法
9
4.子集树与排列树
图5-1和图5-4中的两棵解空间树是回溯法解题时常 遇到的两类典型的解空间树。
当所给的问题是从n个元素的集合S中找出满足某种 性质的子集时,相应的解空间树称为子集树。
例如,n个物品的0-1背包问题相应的解空间树称 为子集树。子集树通常有2n个叶结点,其结点总个 数为2n+1-1。
第五章 回溯法(Backtrack)
回溯法有“通用的解题法”之称。用它可以求出问 题的所有解或任一解。 回溯法是一个既带有系统性又带有跳跃性的搜索法。 它在包含问题所有解的解空间树中,按照深度优先的 策略,从根出发进行搜索。搜索每到达解空间树的一 个结点,总是先判断以该结点为根的子树是否肯定不 包含问题的解。如果肯定不包含,则跳过对该子树的 系统搜索,一层一层地向它的祖先回溯,直到遇上一 个还有未被搜索过的儿子的结点,才转向该结点的一 个未曾搜索过的儿子结点,继续搜索;否则,进入该 子树,继续按深优先的策略进行搜索。
例子:四皇后问题: 给4*4棋盘的行和列分别从左到右和从上到下编号为1, 2,3,4,同时也给4个皇后分别编号为1,2,3,4。 由于要求不同的皇后不能放在同一行,不失一般性,可设 皇后i只放在第i行。
第五章 回溯法 14
╳
1
╳
╳
1 2
3 24
1
2
3
4
2
3 45 46 51 56 61 1 67 4 66
0
I
1
J
1
0 O
0
4
L
50
第五章 回溯法
M
25
图5-2 在0-1背包问题的解空间树上搜索最优解
2. 回溯法的基本思想
确定了解空间的组织结构后,回溯法就从开始 结点(根结点)出发,以深度优先的方式搜索解 空间。这个开始结点就成为一个活结点,同时也 成为当前的扩展结点。在当前的扩展结点处,搜 索向纵深方向移至一个新结点。这个新结点就成 为一个新的活结点,并成为当前的扩展结点。如 果当前的扩展结点处不能再向纵深方向移动,则 当前的扩展结点就成为死结点。此时应回溯到最 近的一个活结点处,并使这个活结点成为当前的 扩展结点。回溯法即以这种工作方式递归地在解 空间中搜索,直至找到所要求的解或解空间中已 无活结点时为止。
第五章 回溯法 16
bool Queen::Place(int k) { for (int j=1; j<k; j++) void Backtrack(int t) if ((abs(k-j)==abs(x[j]-x[k])) { if (t > n) || (x[j]==x[k])) { sum++; return false; for (int i=1;i<=n;i++) else return true; cout << x[i]<< ’ ’ ; } cout << endl; n 1 算法分析 } i n 解空间树中内结点个数: i 0 else for (int i=1;i<=n;i++) 对每个内结点,函数Place检查当前 扩展结点的每一个儿子是否可放 { x[t]=i; 2)。 当前列需耗时 O(n if (Place(t) ) n 1 i 2 总的时间耗费是 = n ( n ) Backtrack(t+1) ; i 0 n+1 } =O(n ) 17 第五章 回溯法 }