《算法设计与分析》第08章
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(3)最优解和目标函数
目标函数,也称代价函数( cost function ),用来衡量每个 可行解的优劣。使目标函数取最大(或最小)值的可行解为 问题的最优解。
3
第8章 回溯法
(4)问题状态和状态空间树
状态空间树( state space )是描述问题解空间的树形结 构。树中每个结点称为一个问题状态(problem state)。 如果从根到树中某个状态的路径代表一个作为候选解的元 组,则称该状态为解状态( solution state )。如果从根 到某个解状态的路径代表一个作为可行解的元组,则称该 解状态为答案状态(answer state)。
14
第8章 回溯法
void NQueens(int k,int n,int *x) { for (int i=0; i<n;i++) { if (Place(k,i,x)) { x[k]=i; if (k==n-1) { for(i=0;i<n;i++)cout<<x[i]<<" "; cout<<endl; } else NQueens(k+1,n,x); } } }
第8章 回溯法
第八章 回溯法
8.1源自文库8.2 8.3 8.4 8.6 8.7
一般方法 8-王后问题 子集和数问题 图的着色问题 0/1背包问题 批处理作业调度
1
第8章 回溯法
8.1 一般方法 8.1.1 基本概念
为便于讨论,先定义下列与回溯法求解问题相关的术语。 (1)显式约束和解空间
规定每个 xi 取值的约 束条件称 为 显式约 束 ( explicit constraint)。 对给定的一个问题实例,显式约束规定了所有可能的元 组,它们组成问题的候选解集,被称为该问题实例的解空 间(solution space)。
21
第8章 回溯法
8.3.2 回溯法求解 解结构形式:可变长度元组和固定长度元组。 可变长度元组(x0,,xk1,xk),0k<n。元组的每 个分量的取值可以是元素值,也可以是选入子集的 正数的下标。 固定长度n-元组(x0,x1,,xn1),xi{0,1}, 0i<n。 xi=0,表示wi未选入子集,xi=1,表示wi入选子集。
10
第8章 回溯法
8.2 n-皇后
8.2.1 问题描述
皇后问题要求在一个 nn的棋盘上放置 n个皇后,使得它们彼 此不受“攻击”。n-皇后问题要求寻找在棋盘上放置这n个皇 后的方案,使得它们中任何两个都不在同一行、同一列或同 一斜线上。
11
第8章 回溯法
8.2.2 回溯法求解
皇后问题 可用 n- 元组( x0, x1,…, xn1 )表示 n- 皇后问题的解,其 中xi表示第i行的皇后所处的列号(0≤xi<n)。 显式约束的一种观点是:Si={0, 1, …, n1},0≤i<n。 相应的隐式约束为:对任意 0≤i, j < n ,当 ij 时, xixj 且。此时的解空间大小为nn。 另一种显式约束的观点是:Si={0, 1, …, n1},0≤i<n ,且 xi xj(0≤i, j < n, ij) 。相应的隐式约束为:对 任意0≤i, j<n,当ij时,。与此相对应的解空间大小 为n!。
26
第8章 回溯法
else if (s+w[k]+w[k+1]<=m) SumOfSub(s+w[k],k+1,r-w[k],x,m,w); if ((s+r-w[k]>=m)&&(s+w[k+1]<=m)) { x[k]=0; SumOfSub(s,k+1,r-w[k],x,m,w); } } void SumOfSub (int* x,int n,float m,float* w) { float r=0; for(int i=0;i<n;i++) r=r+w[i]; if(r>=m && w[0]<=m) SumOfSub(0,0,r,x,m,w); }
2
第8章 回溯法
(2)隐式约束和判定函数
隐式约束( implicit constraint )给出了判定一个候选
解是否为可行解的条件。 一般需要从问题描述的隐式约束 出发,设计一个判定函数 p(x0,x1,…,xn-1) ,使得当且仅当 p(x0,x1,…,xn-1) 为真时, n 元组 (x0,x1,…,xn-1) 是问题实例 的满足隐式约束的一个可行解。
22
第8章 回溯法
23
第8章 回溯法
24
第8章 回溯法
一般称这种从 n 个元素的集合中找出满足某些性质 的子集的状态空间树为子集树。子集树有2n个解状 态,遍历子集树的时间为Ω(2n)。 约束函数: Bk(x0,x1,,xk) 为true,当且仅当
w ixi w i i i k
0
29
第8章 回溯法
30
第8章 回溯法
8.4.2 回溯法求解
设无向图G=(V,E)采用如下定义的邻接矩阵a表示:
1 a[i ][j ] 0
如果(i,j ) E 其它
解 的 形 式 : n- 元 组 (x0,x1,,xn - 1), xi{1 , … , m}, 0i<n,表示结点i的颜色,这就是显式约束。xi=0表示没 有可用的颜色。因此解空间的大小为mn。 隐式约束可描述为:如果边(i,j)E,则 xixj。
12
第8章 回溯法 皇后问题的状态空间树是一棵排列树。排列树有n!个叶结点, 遍历排列树的时间为(n!)。
图8-3 4-皇后问题状态空间树,结点按深度优先遍历编导
13
第8章 回溯法
8.2.3 n-皇后算法 【程序8-4】 n-皇后问题的回溯算法
bool Place(int k, int i,int* x) {//判定两个皇后是否在同一列或在同一斜线上 for (int j=0;j<k;j++) if ((x[j]==i) || (abs(x[j]-i)==abs(j-k))) return false; return true; } void NQueens(int n,int *x) { NQueens(0,n,x); }
j 0 i 0
因此,需要实际生成的结点数目大约占总结点数 的1.55%。
19
第8章 回溯法
图8-7 估计8-皇后问题状态空间树实际大小
20
第8章 回溯法
8.3 子集和数
8.3.1 问题描述 已知n个不同正数wi,0in-1,的集合,求该集合的 所有满足条件的子集,使得每个子集中的正数之和 等于另一个给定的正数M。 例 8- 2 设有n=4个正数的集合 W={w0,w1,w2,w3}=(11,13,24,7)和整数M=31,求W的所 有满足条件的子集,使得子集中的正数之和等于 M 。
4
第8章 回溯法
8.1.2剪枝函数和回溯法
为了提高搜索效率,在搜索过程中使用约束函数 ( constraint function ),可以避免无谓地搜索那些已知 不含答案状态的子树。如果是最优化问题,还可使用限界函 数(bound function)剪去那些不可能包含最优答案结点的 子树。约束函数和限界函数的目的是相同的,都为了剪去不 必要搜索的子树,减少问题求解所需实际生成的状态结点数, 它们统称为剪枝函数(pruning function)。 使用剪枝函数的深度优先生成状态空间树中结点的求解方法 称为回溯法(backtracking);广度优先生成结点,并使用 剪枝函数的方法称为分枝限界法(branch-and-bound)。
31
第8章 回溯法
约 束 函 数 : 对 所 有 i 和 j , 0i,j<k , ij , 若 a[i][j]=1,则xixj。
32
第8章 回溯法
8.4.3 图着色算法 【程序8-6】 图的m着色算法
template <class T> void MGraph<T>::NextValue(int k,int m,int *x) { do { x[k]=(x[k]+1) % (m+1); if (!x[k]) return; for (int j=0; j<k; j++) if (a[k][j] && x[k] == x[j]) break; if (j==k) return; } while (1);
8
第8章 回溯法 蒙特卡罗方法(Monte Carlo)。这种估计方法的基本思想 是在状态空间树中随机选择一条路径(x0, x1,…, xn1)。设X 是这条随机路径上,代表部分向量(x0, x1,…, xk1)的结点, 如果在X处不受限制的孩子数目是mk,则认为与X同层的其他
结点不受限制的孩子数目也都是mk。
6
第8章 回溯法
【程序8-2】 迭代回溯法 Void IBacktrack(int n) { int k=0; while (k>=0){ if (还剩下尚未检测的x[k],使得x[k] T(x[0],,x[k-1]) && Bk(x[0],,x[k]){ if ( (x[0],x[1],,x[k])是一个可行解) 输出(x[0],x[1],,x[k]); k++; } else k--; } }
5
第8章 回溯法
【程序8-1】递归回溯法
Void RBacktrack(int k) {//应以Rbacktrack(0)调用本函数 for ( 每 个 x[k], 使 得 x[k]T(x[0],,x[k-1]) &&(Bk(x[0],,x[k])){ if ( (x[0],x[1],,x[k])是一个可行解) 输出 (x[0],x[1],,x[k]); RBacktrack(k+1); } }
k 1
n 1
M
且
w ixi i
0
k 1
wk M
25
第8章 回溯法
8.3.3 子集和数算法 【程序8-5】子集和数的回溯算法 void SumOfSub (float s,int k,float r,int* x,float m,float* w) { x[k]=1; if (s+w[k]==m) { for (int j=0;j<=k;j++) cout<<x[j]<< ' '; cout<<endl; }
27
第8章 回溯法 例8-3 设有 n=6 个正数的集合 W=(5,10,12,13,15,18) 和整数 M=30 , 求W的所有元素之和为M的子集。
28
第8章 回溯法
8.4 图的着色
8.4.1 问题描述 已知无向图 G=(V,E) 和 m 种不同的颜色,如果只允许 使用这 m 种颜色对图 G 的结点着色,每个结点着一种 颜色。问是否存在一种着色方案,使得图中任意相 邻的两个结点都有不同的颜色。这就是 m- 着色判定 问题(m-colorability decision problem)
整个状态空间树上将实际生成的结点数估计为
m = 1+m0+m0m1+m0m1m2+
9
第8章 回溯法
【程序8-3】 蒙特卡罗算法 int Estimate(SType* x) { int k=0,m=1,r=1; do { SetType S={ x[k]| x[k]T(x[1],,x[k1]) && Bk(x[1],,x[k]==true)}; if (!Size(S)) return m; r=r*Size(S);m=m+r; x[k]=Choose(S);k++; }while(1); }
7
第8章 回溯法
8.1.3 回溯法的效率分析
回溯法的时间通常取决于状态空间树上实际生成的那部分
问题状态的数目。对于元组长度为n的问题实例,若其状态 空间树中结点总数为n!(或2n或nn),则回溯算法的最坏情 况时间复杂度可达O(p(n)n!)(或O(p(n)2n)或O(p(n)nn)), 这里p(n)是n的多项式,是生成一个结点所需的时间。
15
第8章 回溯法
图8-4 4-皇后问题的两个可行解
16
第8章 回溯法
图8-5 回溯法求4-皇后问题的一个可行解
17
第8章 回溯法
图8-6 回溯法实际生成的状态空间树的部分
18
第8章 回溯法
8.2.4 时间分析
可通过计算得到这 5 次试验中实际需要生成的结 点数的平均值为1625。8-皇后问题状态空间树的结 j 7 点总数是: 1 ( 8 i ) 109601