第5章(5.3回溯算法)

合集下载

第5章-回溯法-New剖析

第5章-回溯法-New剖析

第5章 回溯法
回溯法的基本思想
回溯法是带优化的穷举法。 回溯法的基本思想:在一棵含有问题全部可 能解的状态空间树上进行深度优先搜索,解为叶 子结点。搜索过程中,每到达一个结点时,则判 断该结点为根的子树是否含有问题的解,如果可 以确定该子树中不含有问题的解,则放弃对该子 树的搜索,退回到上层父结点,继续下一步深度 优先搜索过程。 在回溯法中,并不是先构造出整棵状态空间 树,再进行搜索,而是在搜索过程中逐步构造出 状态空间树,即边搜索,边构造。
}
遍历排列树需要O(n!)计算时间
第5章 回溯法
八皇后问题
是一个古老而著名的问题。该问题是十九 世纪著名的数学家高斯1850年提出。 在8X8格的国际象棋上摆放八个皇后,使 其不能互相攻击,即任意两个皇后都不能 处于同一行、同一列或同一斜线上,问有 多少种摆法。 高斯认为有76种方案。1854年在柏林的 象棋杂志上不同的作者发表了40种不同的 解,后来有人用图论的方法解出92种结果。
第5章 回溯法
第5章 回溯法
引入问题
回溯是重要的算法之一 要求找到一组解,或要求找到一个满足某些限制 的最优解。 ->通过彻底的搜索方法来解决。
*彻底搜索的运算量很大,有时大到计算机承受 不了的程度。
*彻底的搜索,以进行大量的比较、舍弃、运算 时间为代价。因此,用穷举法解某些实际问题是不 现实的. ->使用回溯法可以大大减少实际的搜索。例如,迷 宫问题,八皇后问题,骑士周游世界问题。
第5章 回溯法
N皇后问题
[问题描述] 在N*N的棋盘上,放置N个皇后,要求每 一横行,每一列,每一对角线上均只能放置一个皇后, 求可能的方案及方案数。
问题的状态即棋盘的布局状态,状态空间树的根为空 棋盘,每个布局的下一步可能布局为该布局结点的子 结点;

第5章 回溯法

第5章  回溯法
第5章
教学要求

回溯
了解回溯算法的概念与回溯设计要领 掌握应用回溯算法求解桥本分数式、素数环、 数码串珠以及情侣拍照等典型案例
本章重点

理解回溯法 “向前走,碰壁回头”的实现
5.1 回溯概述

1. 回溯的概念
(1) 回溯法(Back track method)有“通用解题法”之美 称,是一种比枚举“聪明”的效率更高的搜索技术。

4. 4皇后问题的回溯举例
如何在4×4的方格棋盘上放置4个皇后,使它们互不攻击:

4皇后问题回溯描述
i=1;a[i]=1; while


(1) { g=1;for(k=i-1;k>=1;k--) if(a[i]=a[k] || abs(a[i]-a[k])=i-k) g=0; // 检测约束条件,不满足则返回 if(g && i==4) printf(a[1:4]); // 输出一个解 if(i<4 && g) {i++;a[i]=1;continue;} while(a[i]==4 && i>1) i--; // 向前回溯 if(a[i]==4 && i==1) break; //退出循环结束探索 else a[i]=a[i]+1; }
(2) 回溯描述 对于一般含参量m,n的搜索问题,输入正整数n,m,(n≥m) i=1;a[i]=<元素初值>; while (1) {for(g=1,k=i-1;k>=1;k--) if( <约束条件1> ) g=0; // 检测约束条件,不满足则返回 if(g && <约束条件2>) printf(a[1:m]); // 输出解 if(i<n && g) {i++;a[i]=<取值点>;continue;} while(a[i]=<回溯点> && i>1) i--; // 向前回溯 if(a[i]==n && i==1) break; // 退出循环,结束 else a[i]=a[i]+1; }

算法思想之5回溯法

算法思想之5回溯法

作业2
作业3
3
2
1
3
if (t>n) output(x);
else for (int i=t;i<=n;i++) { swap(x[t], x[i]); if (legal(t)) backtrack(t+1);
这3个作业的6种可能的调度方 案是1,2,3;1,3,2; 2,1,3; 2,3,1; 3,1,2;3,2,1;对应 的完成时间和分别是19, 18, 20,21,19,19。最佳调度方 案是1,3,2。
起始点 1
6 4 30 5 10
生成问题状态的基本方法
活结点 :已生成且其儿子没有全部生成的点 扩展结点 :正在产生儿子的结点 死结点 :所有儿子已经全部产生的结点
活结点 扩展结点 死结点
2
3
20
4
5
6
1
生成问题状态的基本方法
采用深度优先法生成解空间树:如果对一
用回溯法搜索解空间时,可以采用两种 策略避免无效搜索:
f=3+7+8=18
swap(x[t], x[i]); } }
M1
M2
f=4+6+10=20
25
int n, f1, f, bestf; int [][] m; int [] x; int [] bestx; int [] f2;
// 作业数 // 机器 1完成处理时间 // 完成时间和 // 当前最优值 // 各作业所需的处理时间 // 当前作业调度 // 当前最优作业调度 // 机器 2完成处理时间
约束函数
界限函数
void backtrack (int i) { // 搜索第 i层结点 if (i > n) { // 到达叶结点 if (cw>bestw) { 将 x数组的内容拷贝到bestx数组中; bestw = cw; } return ; } r -= w[i]; if (cw + w[i] <= c) { // 搜索左子树 x[i] = 1; cw += w[i]; 增加两个数组: backtrack(i + 1); int[ ] x:记录搜索路径 cw -= w[i]; int[ ] bestx:记录最优路径 } if (cw+r>bestw) { x[i] = 0; backtrack(i + 1); } r += w[i]; }

回溯法

回溯法

西安邮电大学计算机学院
第5章 回溯法
以示例图为例,当 n = 4 时,假定驻地为节点 1,则旅行售货员问题的解空间是:
{ ( 1,2,3,4,1 )、 ( 1,2,4,3,1 )、 ( 1,3,2,4,1 )、 ( 1,3,4,2,1 )、 ( 1,4,2,3,1 )、 ( 1,4,3,2,1 ) },共有(4 - 1)!= 3!= 6 种可能。 当节点数为 n 时,有 (n - 1)!种可能的解(这是一个排列问题)。
计算机科学的先驱、英国科学家阿兰· 麦席森· 图灵
第5章 回溯法
回溯法以深度优先的方式搜索解空间。如果回溯法在执行过程
中判断解空间树的某个节点不包含问题的解时,则跳过对以 该节点为根的子树的搜索(子树中一定不会包含问题的解), 逐层向其祖先节点回溯;否则进入该子树,继续按深度优先策 略搜索。这也是“回溯法”名称的由来。
西安邮电大学计算机学院
第5章 回溯法
5.1.4 迭代回溯
采用树的非递归深度优先遍历算法,可将回溯法表示为一个非递归迭代过程。 void IterativeBacktrack( ) { int t = 1; while ( t > 0 ) { if ( f( n, t ) <= g( n, t ) ) for ( int i = f( n, t ); i <= g( n, t ); i++ ) { x[ t ] = h( i ); if ( Constraint( t ) && Bound( t ) ) { if ( Solution( t ) ) output( x ); else t++; } } else t--; } 回溯法
(2)解空间结构 定义了问题的解空间后,还应将解空间很好地组织起来,使得能用回溯法方便地 搜索整个解空间。通常将解空间组织成树或图的形式。如果将解空间组织成树的

第5章 回溯算法

第5章   回溯算法

第5章 回溯算法
当我们确定了解空间的组织结构以后,回溯算法便可以 从起始结点(根结点)出发,以深度优先方式搜索整个 解空间。于是,这个起始结点既成为活结点,同时又成 为当前的扩展结点。在当前的扩展结点处,搜索过程就 向着纵深方向移动到一个新的结点,而这个新的结点就 成为当前的一个新的活结点,并且成为当前的扩展结点。 如果在当前的扩展结点处不能再向纵深方向移动,那么 当前的这个扩展结点就成为死结点。此时,就不能继续 纵深下去,应立即往回移动(这就是回溯)到最近的一 个活结点处,并且使得这个活结点成为当前的扩展结点。 回溯算法就是以这种方式递归地在解空间中进行不断地 搜索活动,直到找出所需要的解或者解空间中已经不再 有活结点时为止。
第5章 回溯算法
例如,当我们在求解0/1背包问题时,通常在使 用回溯算法的同时采用剪枝函数剪除导致不可行 解的子树。在使用回溯算法求解旅行商问题时, 如果从根结点到当前的扩展结点处的部分周游路 线的成本已经超过了当前找到的周游路线成本, 那么就可以判定以此结点为根结点的子树中不包 含最优解,因此,可以将该子树剪除。

迭代回溯


0/1背包问题
回溯算法求解的经典问题
装箱问题
最大通信团体问题
第5章 回溯算法
回溯算法具有通用的解题算法之称。使用回溯算法可
以系统地搜索一个问题的全部解或者其中的任意一个解。 回溯算法是一个既具有系统性,同时又具有跳跃性的搜 索算法。它在问题的解空间树中,往往可以根据深度优 先策略,由根结点出发依次搜索整棵解空间树。当回溯 算法在搜索到解空间树中的任意一个结点时,应首先判 断该结点是否包含原问题的解。如果包含,就直接进入 到该子树,并且继续按照深度优先策略搜索问题的解; 如果不包含,那么就跳过对以此结点为根结点的子树的 搜索,并且依次逐层向其祖先结点回溯。当我们使用回 溯算法求一个问题的全部解时,通常要回溯到解空间树 的根结点,并且当根结点的所有子树都已经被搜索或者 遍历了一遍之后方能结束。然而,如果当只需要使用回 溯算法求问题的一个解时,通常只需要搜索到问题的一 个解就可以结束。这种以深度优先系统搜索问题的解的 算法称为回溯算法,它适用于求解数据规模比较大的问 题。

第5章 回溯法

第5章 回溯法
14
(1)如果X=(x1, x2, …, xi+1)是问题的最终解,则输出这个解。 如果问题只希望得到一个解,则结束搜索,否则继续搜索其 他解; (2)如果X=(x1, x2, …, xi+1)是问题的部分解,则继续构造解 向量的下一个分量; (3)如果X=(x1, x2, …, xi+1)既不是问题的部分解也不是问题 的最终解,则存在下面两种情况: ① 如果xi+1= ai+1k不是集合Si+1的最后一个元素,则令xi+1= ai+ 1k+1,即选择Si+1的下一个元素作为解向量X的第i+1个分量; ② 如果xi+1= ai+1k是集合Si+1的最后一个元素,就回溯到X=(x1, x2, …, xi),选择Si的下一个元素作为解向量X的第i个分量,假 设xi= aik,如果aik不是集合Si的最后一个元素,则令xi= aik+1; 否则,就继续回溯到X=(x1, x2, …, xi-1); 15
2 3
4
3
4
1
3ห้องสมุดไป่ตู้
1
4
2
4
1
2
1
2
3
3
1
2
1
10 12 15 17 21 23 26 28 31 33 37 39 42 44 47 49 52 54 57 59 62 64 n=4的TSP问题的解空间树
8
解空间树的动态搜索(1)
回溯法从根结点出发,按照深度优先策略遍历 解空间树,搜索满足约束条件的解。 在搜索至树中任一结点时,先判断该结点对应 的部分解是否满足约束条件,或者是否超出目标函 数的界,也就是判断该结点是否包含问题的(最优) 解,如果肯定不包含,则跳过对以该结点为根的子 树的搜索,即所谓剪枝( Pruning );否则,进入 以该结点为根的子树,继续按照深度优先策略搜索。

算法第5章回溯法

算法第5章回溯法

A C此r=时CAr-、w1B=为14活,结V=点V,+vB1=成4为5 当前扩展结点
扩展B,先到达D 再扩• 展CBr<到w达2,ED导致一个不可行解,回溯到B
Cr=C=30,V=0
• E可行,此时A、B、E是活结点,E成为新的扩展结点
• 扩展E,先到达J
B w =16,v =45 C C =30,V=0 • 再次––扩展C由r<E于w到K3,达是JK叶导1结致点一,个即不得可到行一1解个,可回行溯解到xE=(1,0,0),V=45
3

J 不可行解 V=45 C =0,V=50 再扩•• 展C扩Cr=展到3G0达,,GV先=到0,达活N结,点N是为叶A、结C点、,G且,2G5<为5当0,前不扩是展最结优点解,又N不可r扩展,返回到G
x=(1,0,0) 50>45 • 再扩展G到达O,O是叶结点,且0<50,不是最优解,又O不可扩展,返回到G
if (legal(t)) backtrack(t+1); swap(x[t], x[i]);//回溯还原
}
}
回溯法搜索
排列树的一
般算法
5.2 装载问题
有n个集装箱要装上2艘n载重量分别为c1和c2的轮船,其中集
装箱i的重量为wi,且 wi c1 c2 i 1
✓问题:是否有一个合理的装载方案,可将这n个集装箱装上这2
不可行解 V=45 – 25<50 –
CL是r=C叶r-结w3点=0,,且V5=0V>+4v53=,5皆0 得到一个可行解x=(0,1,1),V=50
M – L不可扩展,成为死结点,返回到F
不是 • 再扩展F到达M

– M是叶结点,且25<50,不是最优解

第五章 回溯法

第五章  回溯法

• Cr=C=30,V=0
C为容量,Cr为剩余空间,V为价值。 • A为唯一活结点,也是当前扩展结点。
H D 1 0 I 1
1 B 0 E 1 0 J K
A
0 C 1 F 1 0 L M N 0 G 1 0 O
5.1 回溯法的算法框架
• n=3, C=30, w={16,15,15}, v={45,25,25}
理论上
寻找问题的解的一种可靠的方法是首先列出所有候选解,然后依次检查每一个, 在检查完所有或部分候选解后,即可找到所需要的解。
但是
当候选解数量有限并且通过检查所有或部分候选解能够得到所需解时,上述方
法是可行的。
若候选解的数量非常大(指数级,大数阶乘),即便采用最快的计算机也只能 解决规模很小的问题。
显约束
对分量xi的取值限定。
隐约束 为满足问题的解而对不同分量之间施加的约束。
5.1 回溯法的算法框架
解空间(Solution Space)
对于问题的一个实例,解向量满足显式约束条件的所有多元组,构成了该 实例的一个解空间。 注意:同一问题可有多种表示,有些表示更简单,所需状态空间更小(存储 量少,搜索方法简单)。
回溯法引言
以深度优先的方式系统地搜索问题的解的算法称为回溯法 使用场合
对于许多问题,当需要找出它的解的集合或者要求回答什么解是满足某些
约束条件的最佳解时,往往要使用回溯法。 这种方法适用于解一些组合数相当大的问题,具有“通用解题法”之称。 回溯法的基本做法 是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法。
一个正在产生儿子的结点称为扩展结点
活结点(L-结点,Live Node)
一个自身已生成但其儿子还没有全部生成的节点称做活结点

第五部分 回溯法

第五部分 回溯法

1
装载问题
• 有一批共n个集装箱要装上2艘载重量分别为c1和c2 n 的轮船,其中集装箱i个重量为wi,且 ∑ wi ≤ c1 + c2 • 装载问题要求确定,是否有一个合理的装载方案 可将这n个集装箱装上这2艘轮船。如果有,找出 n 2 一种装载方案。
– 例如,当n=3, c1=c2=50, 且w=[10,40,40]时,则可以将集 装箱1和2装到第一艘轮船上,而将集装箱3装到第二艘 轮船上;如果w=[20,40,40],则无法将这3个集装箱都装 上轮船。
• 限界函数
– 例如,c=7, w=[3, 5, 2, 1], v=[9, 10, 7, 4] 。v/w=[3, 2, 3.5, 4]。以物品单位重量价值的递减序装入物品。装入物品 4、3、1后,只能装入0.2的物品2,由此得到一个解 Bound (i) x=[1, 0.2, 1, 1],其相应的价值为22。尽管这个解不是一 //计算上界 个可行解,但其价值是最优值的一个上界,即对于该 cleft = c - cw // 剩余容量 问题,最优值不超过22。 bound = cp //以物品单位重量价值递减序装入物品 while i <= n and w[i] <= cleft O(n) cleft = cleft - w[i] bound = bound + p[i] i++ //装满背包 if i <= n bound = bound + p[i] / w[i] * cleft return bound
• • • •
活结点:自身已生成但其儿子结点还未全部生成的结点 扩展结点:当前正在处理的结点 死结点:所有儿子已经生成 叶结点:可行解 0-1背包:w=[16,15,15], v=[45,25,25], c=30

第5章 回溯法

第5章 回溯法
◎四川师范大学 计算机科学学院 刘芳 27
算法设计与分析<<回溯法
小结
回溯法解题的特征
在深度优先搜索过程中动态产生问题的解空间。 几个术语
扩展结点:一个正在产生儿子的结点称为扩展结点 活结点:一个自身已生成但其儿子还没有全部生成的
结点称做活结点 死结点:一个所有儿子已经产生的结点称做死结点。
有限集, 设已有满足约束条件的部分解(x1, x2,… xi)添 加xi+1 si+1,
若(x1, x2,… xi xi+1)满足约束条件, 则继续添加xi+2 ; 若所有可能的xi+1 si+1均不满足约束条件,则去掉xi ,
回溯到(x1, x2,… xi-1), 添加尚未考虑过的xi;
回溯法 分支限界法
◎四川师范大学 计算机科学学院 刘芳 3
算法设计与分析<<回溯法
问题的解空间
问题的解向量:
问题的解可以表示成一个n元式(x1, x2,… xn)的形式。
问题的解空间
E={(x1, x2,… xn)| xi si , si为有限集 }称为问题的解空

约束条件
分析:
可能解由一个等长向量(x1, x2, …, xn)组成, 其中 如:
xi=1(1≤i≤n)表示物品i装入背包 xi=0(1≤i≤n)表示物品i没有装入背包 当n=3时,其解空间是:
{ (0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1) }
骤,而每一个步骤都有若干种可能的分支,为了完成 这一过程,又必须遵守一些规则,

第5章 回溯法

第5章 回溯法
30 A 5 6 B
4
C 20 D
10
求赋权图G 的具有最小 权 的 Hamilton圈
B
C D B
C
D B
D
C
D
C
D
B
C
B
A
5
5.1回溯法的算法框架—基本思想
例2.定和子集问题:
已知一个正实数的集合 A={w1,w2,……wn},和正实数M.试求A的所有子集S,使得S中 的数之和等于M。 这个问题的解可以表示成0/1数组{x1,x2,……xn},依据w1是 否属于S,x1分别取值1或0。故解空间中共有2n个元素。它的树 1 结构是一棵完全二叉树。
7
5.1回溯法的算法框架—基本思想
从例3来看,解空间的确定与我们对问题的描述有关。 如何组织解空间的结构会直接影响对问题的求解效率。这是 因为回溯方法的基本思想是通过搜索解空间来找到问题的可 行解以至最优解。 当所给的问题是从n个元素的集合S中找出满足某种性质 的子集时,相应的解空间树称为子集合树。此时,解空间有 2n 个元素,遍历子集树的任何算法均需Ω(2n)的计算时间。 如例2。 当所给的问题是确定n个元素的满足某种性质的排列时, 相应的解空间树称为排列树,此时,解空间有n!个元素。遍 历排列树的任何算法均需Ω(n!)计算时间,如例1和例3。本 章只讨论具有上两类解空间树的求解问题。
11
5.1回溯法的算法框架—递归回溯
回溯法对解空间作深度优先搜索,因此,在一般情况下 用递归方法实现回溯法。 void backtrack (int t) { if (t>n) output(x); else for (int i=f(n,t); i<=g(n,t);i++) { x[t]=h(i); if (constraint(t) && bound(t)) backtrack(t+1); } } f(n,t)和g(n,t)分别表示在当前扩展结点处未搜索过子 树的起始编号与终止编号,h(i)表示当前扩展结点处x[t]的 第i个可选值。

第5章回溯法(YZW)

第5章回溯法(YZW)
搜索过程直到找到问题的解或根结点变成死结点为止。
示例:n后问题
问题描述: 在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际 象棋的规则,皇后可以攻击与之处在同一行或同一列或同 一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n 个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。
1
1
2
3 4
2
例: 4-皇后问题
1 结点2的所有儿子表示的都是 x1= 2 x1=1 不可能导致答案的棋盘格局, 因 此结点2也被杀死; 再回溯到结 18 2 点1生成结点18, 路径变为(2) x2= 4 x2= 1 x2= 2 结点18的儿子结点19、 x2= 3 x2= 3 结点24被杀死, 应回溯 24 13 19 8 3 1 x3=2 kill kill kill x3=4 2 x3=2 x3=3 1 9 kill 1 2 11 14 kill x4=3 15 kill 16 kill
用约束函数在扩展结点处剪去不满足约束的
子树即:导致不可行解的结点; 用限界函数剪去得不到最优解的子树。即: 导致非最优解的结点。 几个名词
扩展结点:一个正在产生儿子的结点称为扩展结点 活结点:一个自身已生成但其儿子还没有全部生成的节点
称做活结点 死结点:一个所有儿子已经产生的结点称做死结点 搜索树:搜索过程中动态形成的树
1 2 3 4 5 Q Q Q Q Q Q
6 7 8
Q
Q 1 2 3 4 5 6 7 8
定义问题的解空间 解的形式:(x1, x2, … , xn) xi的取值范围:xi=1,2, … ,n 组织解空间 满n叉树,树的深度为n 搜索解空间 约束条件:不同列且不处于同一正、反对 角线上:|i-j||xi-xj| 限界条件:(×) 搜索过程(以4皇后问题为例)

(算法分析设计)第5章回溯法

(算法分析设计)第5章回溯法
展结点就成为死结点。此时,应往回移动(回溯)到最近
的活结点处,并使该结点成为当前的扩展结点。
– 回溯法按上述方式递归地在解空间中搜索,直到找到所 要求的解或解空间中无活结点为止。
7
实例分析
• n=3的0-1背包问题
– w=[16,15,15] – p=[45,25,25] – c=30
8
解空间为:
• 问题的解空间 • 回溯法的基本思想 • 递归回溯 • 迭代回溯 • 子集树与排列树
4
问题的解空间
• 解空间
– 应明确问题的解空间的定义
• 问题的解空间至少应包含问题的一个(最优解)。
– 对问题解空间进行组织
• 通常组织为树或图的形式。 ——有利于回溯法对整个解空间的搜索
5
知识点
• 问题的解空间 • 回溯法的基本思想 • 递归回溯 • 迭代回溯 • 子集树与排列树
backtrack(t+1);
32
旅行商问题(TSP)
1 6
30 2
5 10
4


20
4顶点的无向带权图

1

23
4


3
42
4

2
3
F G H IJ K
4
3
4
23
2
L M N OP Q
n=4的TSP问题的解空间树(排列树)
33
排列树
• 排列树
– 当所给问题是确定n个元素满足某种性质的排 列时,相应的解空间树被称为排列树.
的子树不可能包含更优的解,剪去。
46
#include <iostream.h> #include <iomanip.h> const int n=4; //图的顶点数

第5章(5.3回溯算法)

第5章(5.3回溯算法)
1、问题提出 已知n个物体重量为:w1、w2… n个物体价值为:p1、p2… 背包载重为:M
两类背包问题:
①普通背包问题(贪心算法) 物体i可以部分的装入背包,若物体i的一部分xi装入 背包,则装入的重量为wi*xi,装入的价值为pi*xi; ②0-1背包问题(回溯算法) 每一件物体不能分割,要么全部放入,要么全部不 放入,称为0-1背包问题;
void backtrack (int t) { if (t>n) output(x); else for (int i=t;i<=n;i++) { swap(x[t], x[i]); if (legal(t)) backtrack(t+1); swap(x[t], x[i]); } }
补充: 0-1背包问题
x[2]=1 19
x[2]=4 x[2]=3 24 29
13
x[3]=2 x[3]=3

… …
x[3]=4 9 11
x[3]=3 x[3]=1 x[3]=1 x[3]=3 x[3]=4 x[3]=4
14
16
20
x[3]=4
22
25
27
30
32
x[4]=4
x[4]=3 x[4]=4 x[4]=3 x[4]=3
例5-5: n皇后问题
4、算法描述 对于n皇后问题的解空间共有nn个叶子节点,最多 有n* nn个节点; 最坏的情况下每个节点都要用place函数判断是否 可行,每一个节点判断时间为O(n); 故该算法的时间复杂度记为O(n* n*nn)= O(nn+2)
5.3.4 满m叉树
• 当所给问题的n个元素中每一个元素均有m种选择, 要求确定其中的一种选择,使得对这n个元素的选择 结果组成的向量满足某种性质,即寻找满足某种特性 的n个元素取值的一种组合。 这类问题的解空间树称为满m叉树。 • 解的形式为n元组(x1,x2,……,xn),分量 xi(i=1,2,……,n)表示第i个元素的选择为xi

第5章回溯法

第5章回溯法

作业1 作业1
对于n 对于n×m的棋盘,从(1,1)开始是否存在 的棋盘,从(1,1)开始是否存在 一条不重复的跳完所有棋盘格的路径,若存 在请给出该路径的描述?对任意的n,m 在请给出该路径的描述?对任意的n,m 是否 总是存在这样一条路径?若不是,能否给出 其存在的充要条件?
B3 A2 A1 A B1 B2 C2 C1 D3 D2 E1 D1
跳马问题
5. 从C2出发,有四条路径可以选择,选择D4, C2出发,有四条路径可以选择,选择D4,
从D4出发又有两条路径,选择E1错误,返 D4出发又有两条路径,选择E1错误,返 回D4选择E2,从E2出发有两条路径,先 D4选择E2,从E2出发有两条路径,先 选择F1错误,返回E2选择B,而B 选择F1错误,返回E2选择B,而B恰好是 我们要到达的目标点,至此,一条路径查找 成功。
回溯算法(一)
什么是回溯
迷宫游戏
入口 回溯
回溯 回溯
什么是回溯法
回溯法是一个既带 有系统性又带有跳跃 性的的搜索算法 性的的搜索算法
索问题 回溯法是以深度优先的方式系统地搜索问题 出口 深度优先 的解, 它适用于解一些组合数较大的问题。 的解 它适用于解一些组合数较大的问题。
n皇后问题
既然回溯算法是由一个节点开始逐步扩展的, 因此我们采用把皇后一个一个的放到棋盘上 的方式来分析问题。
n皇后问题
首先要把第一个皇后放到棋盘上由于第一个皇后有 n列可以放,因此可扩展出n种情况。先选其中一列 列可以放,因此可扩展出n 放下这个皇后; 然后开始放第二个皇后。同样第二个皇后也有n 然后开始放第二个皇后。同样第二个皇后也有n列 可以放,因此也能扩展出n 可以放,因此也能扩展出n种情况,但第二个皇后 可能会和第一个皇后发生攻击,而一旦发生攻击, 就没有必要往下扩展第三个皇后,而如果没有发生 攻击,则继续放第三个皇后; 依此类推,直到n 依此类推,直到n个皇后全都放下后,即得到一组 可行解。 扩展全部完成后即可得到结果。

《算法设计与分析》-第五章 回溯法

《算法设计与分析》-第五章 回溯法
回溯法的应用—n后问题 后问题
例1(8-皇问题)
皇问题) 例1(8-皇问题) ( 皇问题
在8×8的棋盘上放置8个皇后,使得这8个皇 后不在同一行,同一列及同一斜角线上.如下 1 2 3 4 5 6 7 8 图6.1: Q
1 2 3 4 5 6 7 8
Q Q Q Q Q Q Q
5.1 回溯法的基本思想
(1)解空间 设问题的解向量为X=(x1,x2,…,xn) ,xi的取值范 围为有穷集Si .把xi的所有可能取值组合,称 为问题的解空间.每一个组合是问题的一个可 能解.
5.1 回溯法的基本思想
(1)解空间 例:0/1背包问题,S={0,1},当n=3时,0/1背 包问题的解空间是: {(0,0,0),(0,0,1),(0,1,0),(0,1,1),(1,0,0),(1,0,1),(1, 1,0),(1,1,1)} 当输入规模为n时,有2n种可能的解.
A 2 C 3 F 4 L 4 2 G H 3 4 M N 1 B 3 D
4 4 I 2 O E 2 J 3 P 3 K 2 Q
----排列树 解空间大小: n!
5.1 回溯法的基本思想
(3)状态空间树的动态搜索
可行解和最优解: 可行解:满足约束条件的解,解空间中的一个子集 最优解:使目标函数取极值(极大或极小)的可行解,一 个或少数几个 例:货郎担问题,有nn种可能解. n!种可行解,只有一个或 几个解是最优解. 例:背包问题,有2n种可能解,有些是可行解,只有一个或 几个是最优解. 有些问题,只要可行解,不需要最优解,例如八后问题.
5.1 回溯法的基本思想
回溯法(backtracking)是一种系统地搜索问 题解的方法.为实现回溯,首先需要定义一个 解空间(solution space),然后以易于搜索 的方式组织解空间,最后用深度优先的方法搜 索解空间,获得问题的解.

第五章 回溯算法

第五章 回溯算法

的结点
» 扩展结点:正在产生儿子的结点
» 死结点:所有儿子已经全部产生的结点
活结点
扩展结点
死结点
4
» 采用深度优先法生成解空间树:如果对一
个扩展结点R,一旦产生了一个儿子 C,就 将 C 当做新的扩展结点。在完成对子树 C 的穷尽搜索后,将 R 再次变成扩展结点, 继续生成 R 的下一个儿子。
扩展结点
这3个作业的6种可能的调度方 案是1,2,3;1,3,2;2,1,3; 2,3,1;3,1,2;3,2,1;对应 的完成时间和分别是19,18, 20,21,19,19。最佳调度方 案是1,3,2。
f=3+7+8=18
M1 M2 f=4+6+10=20
26
void backtrack (int t) { if (t>n) output(x); else for (int i=t;i<=n;i++) { swap(x[t], x[i]); if (legal(t)) backtrack(t+1); swap(x[t], x[i]); } }
27
void backtrack (int t) { if (t>n) output(x);
else
for (int i=t;i<=n;i++) { swap(x[t], x[i]); if (legal(t)) backtrack(t+1); swap(x[t], x[i]); } }
void backtrack(int i) { if (i > n) { for (int j = 1; j <= n; j++) bestx[j] = x[j]; bestf = f; } else for (int j = i; j <= n; j++) { f1+=m[x[j]][1]; f2[i]=((f2[i-1]>f1)?f2[i-1]:f1)+m[x[j]][2]; f+=f2[i]; if (f < bestf) { swap(x,i,j); backtrack(i+1); swap(x,i,j); } f1-=m[x[j]][1]; f-=f2[i]; } }
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

例5-5: n皇后问题
2、问题分析
该问题可用一个n元数组x[ ]来表示n皇后问题的解; x[ i]表示皇后i放在棋盘的第i行,第x[ i]列; 皇后i与皇后j之间互相不攻击的条件: ①不再同一行: i≠j ②不再同一列: i≠j,且 x[ i] ≠ x[ j] ③不再同一斜线(对角线)上: (i, x[ i])与 (j, x[ j]) 主对角线及其平行线特点:斜率为-1 或 (行号-列号) 相等; 不在主对角线: i - x[ i] ≠ j - x[ j] 负对角线及其平行线特点:斜率为1 或 (行号+列号) 相等; 不在负对角线: i + x[ i] ≠ j + x[ j] ③ 等价于| i- j | ≠ | x[ i] - x[ j] |
void backtrack (int t) { if (t>n) output(x); else for (int i=t;i<=n;i++) { swap(x[t], x[i]); if (legal(t)) backtrack(t+1); swap(x[t], x[i]); } }
补充: 0-1背包问题
x[4]=2
x[4]=3 x[4]=4 x[4]=1 x[4]=3
x[4]=1
17
21
23
26
28
31
33
例5-5: n皇后问题
4、算法描述
double nqueen(int nn) { int n=nn; int sum=0; // 放置皇后的方案数 int x[ n]; // x[ i]表示皇后i放在棋盘的第i行,第x[ i]列 for (int i=0;i<=n; i++;) x[ i]=0; // 初始化 backtrack(1); return sum; } // 回溯搜索解空间
例5-5: n皇后问题
4、算法描述 对于n皇后问题的解空间共有nn个叶子节点,最多 有n* nn个节点; 最坏的情况下每个节点都要用place函数判断是否 可行,每一个节点判断时间为O(n); 故该算法的时间复杂度记为O(n* n*nn)= O(nn+2)
5.3.4 满m叉树
• 当所给问题的n个元素中每一个元素均有m种选择, 要求确定其中的一种选择,使得对这n个元素的选择 结果组成的向量满足某种性质,即寻找满足某种特性 的n个元素取值的一种组合。 这类问题的解空间树称为满m叉树。 • 解的形式为n元组(x1,x2,……,xn),分量 xi(i=1,2,……,n)表示第i个元素的选择为xi
2、基本思路 ①确定问题的解空间,并将解空间组织成易于查找的 子集树的形式;
1 1 2 1 3 0 9
0
6
1 10 0 8
0 13
1
4
0
5
1 7
1 11
0 12
Hale Waihona Puke 1 14015
②以深度优先的方式搜索整个解空间,遇到不满足 要求的节点就回溯,沿另一个分支继续搜索;
3、举例 背包载重:M=10 物品重量:w1=6、w2=5、w3=5 物品价值:p1=42、p2=25、p3=30 首先,定义问题的解空间(子集树); 然后,深度优先搜索解空间(无剪枝函数);
x[2]=1 19
x[2]=4 x[2]=3 24 29
13
x[3]=2 x[3]=3

… …
x[3]=4 9 11
x[3]=3 x[3]=1 x[3]=1 x[3]=3 x[3]=4 x[3]=4
14
16
20
x[3]=4
22
25
27
30
32
x[4]=4
x[4]=3 x[4]=4 x[4]=3 x[4]=3
1、问题提出 已知n个物体重量为:w1、w2… n个物体价值为:p1、p2… 背包载重为:M
两类背包问题:
①普通背包问题(贪心算法) 物体i可以部分的装入背包,若物体i的一部分xi装入 背包,则装入的重量为wi*xi,装入的价值为pi*xi; ②0-1背包问题(回溯算法) 每一件物体不能分割,要么全部放入,要么全部不 放入,称为0-1背包问题;
void backtrack ( int t) { if( t>n ) // 搜索到叶子节点,方案数+1,t是层数 sum++; else for( int i=1; i<=n; i++) // 第t个皇后行号t,i列号 { x[ t]=i; // 将第t个皇后放在t行,i列 if( place(t) ) // 判断是否有冲突 backtrack (t+1); // 放下一个皇后 } } void place( int k) { for( int j=1;j<k; j++ ) //k之前的皇后1…k-1是否与k冲突 if( math.abs(k-j)=math.abs(x[ k]-x[ j]) ) return false; else return true; }
A1=4 A2=5
A3=4
A4=4
A5=5
A6=4
A7=5
A8=3
Step1:按照节点度数,先用第一种颜色对A7着色,与A7不相邻节点A2用 同一颜色着色; Step2:按节点度,用第二种颜色对A5着色,与A5不相邻节点A1用同一颜 色着色; Step3:按节点度,用第三种颜色对A4着色,与A4不相邻节点A3, A8用同 一颜色着色; Step4:按节点度,用第四种颜色对A6着色;
例5-11: 图的着色问题
1、问题提出
给定无向连通图G和m种不同的颜色; 用这m种颜色为图G的各个顶点着色,是否有一种方法使得 图G中每一条边的两个顶点着不同颜色; 典型的应用: 地图着色,在一个平面或球面的地图,使用4种颜色进行着 色,可以使相邻国家的颜色不一致。 例: 如左图表示一张地图,把该地图转换成平面图如右图.
5.3
回溯算法
1、回溯算法基本思想 回溯算法是一种搜索算法,其基本思想是在搜索尝试中找问 题的解,当不满足求解条件就”回溯”返回,尝试别的路径。 通俗地讲:回溯法是一种“能进则进,进不了则换,换不了 则退”的基本搜索方法 基本思想: 回溯法在问题的解空间树中,按深度优先策略,从根结点出 发搜索解空间树。 算法搜索至解空间树的任意一点时,先判断该结点是否包含 问题的解。 如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层 向其祖先结点回溯; 否则,进入该子树,继续按深度优先策略搜索。
5、算法分析
该算法计算上界函数bound时间复杂度为O(n); 在最坏的情况下,有2n/2个右孩子节点需要计算上界; 故该算法的时间复杂度记为O(n*2n-1)
例5-5: n皇后问题
1、问题提出
在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际 象棋的规则,皇后可以攻击与之处在同一行或同一列或同一 斜线上的棋子。 令n=8; 8皇后问题:等价于在8×8格的棋盘上放置8个 皇后,任何2个皇后不放在同一行或同一列或同一斜线上。 1 Q 2 Q 3 Q 4 Q 5 Q 6 Q 7 Q 8 Q 1 2 3 4 5 6 7 8
x[3]=2
x[1]=2
x[1]=3 18
x[1]=4
x[2]=1 19
x[2]=4 x[2]=3
24 29
13 x[3]=4 11
x[3]=2 x[3]=3

32
x[3]=1 x[3]=1 x[3]=3 x[3]=3 x[3]=4 x[3]=4
14
16
20 x[4]=4
22
25
27
30
… …
x[4]=3 x[4]=4 x[4]=3 x[4]=3 x[4]=4 5 7 10 12 15
解空间树:子集树与排列树
遍历子集树需O(2n)计算时间
void backtrack (int t) { if (t>n) output(x); else for (int i=0;i<=1;i++) { x[t]=i; if (legal(t)) backtrack(t+1); } }
遍历排列树需要O(n!)计算时间
x1=1
x1=2
x1=3
x2=1 x3=1 2 3
2 1 2
3 3 1 2 3 1 2
x2=1 3 1
2 2 3
3 3 1
x2=1 3 1
2 2 3
3 1 3
2
2
2
满3叉树
树的根结点:初始状态 中间结点:某种情况下的中间状态 叶子结点:结束状态 分支:从一个状态过渡到另一个状态的行为 从根结点到叶子结点的路径:一个可能的解(n个元素 值的一个组合) 子集树的深度:等于问题的规模。
4 1 3 5 2 2 5 3
1
4
2、解决方法
法1:well—powell算法 step1:将图的节点按度数递减排序; step2:用第1种颜色给第1个节点着色; 并按节点排列顺序,用同一种颜色给对不相邻的节 点 着色; step3:按节点度数,顺序选择下一个节点用step2方法着 色,直到所有节点全部着色;
1 0 1 2
(当前价值+剩余价值) 0+55>42故进入右子树
9
1 3
0
6
1
(当前价值+剩余价值) 0+30<55,不进入右子树 0 13
10 0
1
4
0
5
1
7
1
8
0
1
0 15
11
12
14
bestp=55
4、算法描述
double knaspack(double p[ ], double w[ ], double c) //c是背包载重 {double cw=0; //当前重量 double cp=0; //当前价值 double bestp=0; //当前最优装载价值 backtrack(1); //回溯搜索解空间 return bestp; }
相关文档
最新文档