第5章 回溯法
第5章-回溯法-New剖析
第5章 回溯法
回溯法的基本思想
回溯法是带优化的穷举法。 回溯法的基本思想:在一棵含有问题全部可 能解的状态空间树上进行深度优先搜索,解为叶 子结点。搜索过程中,每到达一个结点时,则判 断该结点为根的子树是否含有问题的解,如果可 以确定该子树中不含有问题的解,则放弃对该子 树的搜索,退回到上层父结点,继续下一步深度 优先搜索过程。 在回溯法中,并不是先构造出整棵状态空间 树,再进行搜索,而是在搜索过程中逐步构造出 状态空间树,即边搜索,边构造。
}
遍历排列树需要O(n!)计算时间
第5章 回溯法
八皇后问题
是一个古老而著名的问题。该问题是十九 世纪著名的数学家高斯1850年提出。 在8X8格的国际象棋上摆放八个皇后,使 其不能互相攻击,即任意两个皇后都不能 处于同一行、同一列或同一斜线上,问有 多少种摆法。 高斯认为有76种方案。1854年在柏林的 象棋杂志上不同的作者发表了40种不同的 解,后来有人用图论的方法解出92种结果。
第5章 回溯法
第5章 回溯法
引入问题
回溯是重要的算法之一 要求找到一组解,或要求找到一个满足某些限制 的最优解。 ->通过彻底的搜索方法来解决。
*彻底搜索的运算量很大,有时大到计算机承受 不了的程度。
*彻底的搜索,以进行大量的比较、舍弃、运算 时间为代价。因此,用穷举法解某些实际问题是不 现实的. ->使用回溯法可以大大减少实际的搜索。例如,迷 宫问题,八皇后问题,骑士周游世界问题。
第5章 回溯法
N皇后问题
[问题描述] 在N*N的棋盘上,放置N个皇后,要求每 一横行,每一列,每一对角线上均只能放置一个皇后, 求可能的方案及方案数。
问题的状态即棋盘的布局状态,状态空间树的根为空 棋盘,每个布局的下一步可能布局为该布局结点的子 结点;
第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; }
2020-wfx-第5章 回溯法-概述
//产生一个可能的解分量
法 框
…
//其他操作
if (constraint(i) && bound(i))
backtrack(i+1); //满足约束条件和限界函数,继续下一层
ห้องสมุดไป่ตู้
架
}
}
}
(2)解空间为排列树
int x[n];
//x存放解向量,并初始化
void backtrack(int i)
//求解排列树的递归框架
{ if(i>n)
//搜索到叶子结点,输出一个可行解
输出结果;
else
{ for (j=i;j<=n;j++)
//用j枚举i所有可能的路径
{…
//第i层的结点选择x[j]的操作
swap(x[i],x[j]);
//为保证排列中每个元素不同,通过交换来实现
if (constraint(i) && bound(i))
3
{2,3,1}
1
{2,3,1}
2
{3,2,1}
1
{3,2,1}
1
{3,1,2}
2
{3,1,2}
回溯法的求解过程
在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点 (开始结点)出发搜索解空间树。
首先根结点成为活结点,同时也成为当前的扩展结点。 在当前的扩展结点处,搜索向纵深方向移至一个新结点。如果在当前的扩 展结点处不能再向纵深方向移动,则当前扩展结点就成为死结点。此时应往回 移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。 递归地在解空间中搜索,直至找到所要求的解或解空间中已无活结点为止。
第5章 回溯法
(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 );否则,进入 以该结点为根的子树,继续按照深度优先策略搜索。
第五章 回溯法
• 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后问题
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
图1 四个顶点的带权图
F
4 L L 59
K
2 Q Q
O
60+6>59 25
第五章 回溯法
19+6=25 29+30>25
活结点 当前扩展结点 死结点 D B 1 A
0 1 F 0
K
45
1
0
E
C 0 G 0 1 N
25
死结点 1
1
H
0
I
1
J
0 O
0
4
L
50
M
25
图5-2 在0-1背包问题的解空间树上搜索最优解
第五章 回溯法
例2:旅行售货员问题:某售货员要到若干城市推销商 品,已知各城市间的路程(或旅费)。他要选一条从 驻地出发,经过每个城市一遍,最后回到驻地的路线 使总的路程(总的旅费)最小。
第五章 回溯法 2
2. 解空间树
通常把解空间组织成解空间树。 例如:对于n=3时的0-1背包问题,其解空间用一 棵完全二叉树表示,如下图所示。
1
A
0
B
1 0 1
C
0
D 1 H
0 1
E
0
F
1 0 1
G
0
I
J
K
L
M
N
O
0-1背包问题的解空间树
第五章 回溯法
3
3. 搜索解空间树的过程
第五部分 回溯法
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章 回溯法
算法设计与分析<<回溯法
小结
回溯法解题的特征
在深度优先搜索过程中动态产生问题的解空间。 几个术语
扩展结点:一个正在产生儿子的结点称为扩展结点 活结点:一个自身已生成但其儿子还没有全部生成的
结点称做活结点 死结点:一个所有儿子已经产生的结点称做死结点。
有限集, 设已有满足约束条件的部分解(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) }
骤,而每一个步骤都有若干种可能的分支,为了完成 这一过程,又必须遵守一些规则,
05回溯法
第5章回溯法回溯法也称为试探法,该方法首先暂时放弃关于问题规模大小的限制,并将问题的候选解按某种顺序逐一枚举和检验。
当发现当前候选解不可能是解时,就选择下一个候选解;倘若当前候选解除了还不满足问题规模要求外,满足所有其他要求时,继续扩大当前候选解的规模,并继续试探。
如果当前候选解满足包括问题规模在内的所有要求时,该候选解就是问题的一个解。
在回溯法中,放弃当前候选解,寻找下一个候选解的过程称为回溯。
扩大当前候选解的规模,以继续试探的过程称为向前试探。
回溯法的基本思想:确定了解空间的组织结构后,回溯法就从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。
这个开始结点就成为一个活结点,同时也成为当前的扩展结点。
在当前的扩展结点处,搜索向纵深方向移至一个新结点。
这个新结点就成为一个新的活结点,并成为当前扩展结点。
如果在当前的扩展结点处不能再向纵深方向移动,则当前扩展结点就成为死结点。
换句话说,这个结点不再是一个活结点。
此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。
回溯法即·96· ACM 程序设计培训教程以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已没有活结点时为止。
运用回溯法解题通常包含以下三个步骤: (1)针对所给问题,定义问题的解空间; (2)确定易于搜索的解空间结构;(3)以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索;5.1〖案例1〗组合问题找出从自然数1、2、……、n 中任取r 个数的所有组合。
例如n=5,r=3的所有组合为:(1)1、2、3 (2)1、2、4 (3)1、2、5 (4)1、3、4 (5)1、3、5 (6)1、4、5 (7)2、3、4 (8)2、3、5 (9)2、4、5 (10)3、4、5则该问题的状态空间为:E={(x1,x2,x3)∣xi ∈S ,i=1,2,3},其中:S={1,2,3,4,5} 约束集为:x1<x2<x3显然该约束集具有完备性。
第5章 回溯法
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)
示例: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章回溯法
的活结点处,并使该结点成为当前的扩展结点。
– 回溯法按上述方式递归地在解空间中搜索,直到找到所 要求的解或解空间中无活结点为止。
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
3
4
20
4顶点的无向带权图
A
1
B
23
4
C
D
3
42
4
E
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; //图的顶点数
回溯法 ppt课件
回溯法举例:
[旅行商问题] 在这个问题中 ,给出一个n 顶点网络(有向 或无向) ,要求找出一个包含所有n 个顶点的具有最小耗 费的环路 。任何一个包含网络中所有n 个顶点的环路被称 作一个旅行(t o u r )。在旅行商问题中 ,要设法找到一 条最小耗费的旅行。 [分析]图给出了一个四顶点网络 。在这个网络中 ,一些旅
Bound(t) : 返回的值为true时 , 在当前扩展节点处 x[1: t]的取值为时 目标函数越界 , 还需由Backtrack(t+1) 对其相应的子树做进一步搜索 。否则 , 当前扩展节点处 x[1: t]的取值是目标函数越界 ,可剪去相应的子树
for循环作用: 搜索遍当前扩展的所有未搜索过的 子树。
si+1均不满足约束条件,则去掉xi , 回溯到(x 1 , x 2 , … xi-1), 添加尚 未考虑过的xi , 如此反复进行,直到(x1 , x2 , … xk) k n满足所有的 约束条件或证明无解.
E= { (x1 , x2 , … xn), xi si , si为有限集 }称为问题的解空间.
5. 1 回溯法基本思想
穷举法技术建议我们先生成所有的候选解 , 然后找出那个 具有需要特性的元素
1 、 回溯法主要思想是每次只构造解的一个分量 ,然后按照 鲜明的方法来评估这个部分构造解 。如果一个部分构造解可以进一 步构造而不会违反问题的约束 , 我们就接受对下一个分量所作的第 一个合法选择 。如果无法对下一个分量进行合法的选择 , 就不对剩 下的任何分量再做任何选择了 。在这种情况下 ,该算法进行回溯 , 把部分构造解的最后一个分量替换为它的下一个选择。
算法模式 Procedure BACKTRACK (n); {k := l;
第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个皇后全都放下后,即得到一组 可行解。 扩展全部完成后即可得到结果。
课件:第五章回溯法
else if (aSaisfeg(oa)o)d{)R{reeccoorrdd((i为,a)a;末); 尾标记。
if ((ai =is=gno)al) {unfinish = false; output( );}
else i{fi+(a+h; aLs.sPounssh)(L1,.P2u, s…h-,Sno,n-s1()a;)}
启发式的搜索 从初始状态开始,每次选择最有可能达到终 止状态的结点进行搜索。
2021/11/25
计算机算法设计与分析
5
三种搜索的优劣之处
• 一般来说,三种搜索方法各有优劣之处:
• 广度优先搜索的优点是一定能找到解;缺点是 空间复杂性和时间复杂性都大。
• 深度优先搜索的优点是空间复杂性和时间复杂 性较小;缺点是不一定能找到解。
• 栈中的结点是分层次的,而现在没有区分它们 的层次。这就增加了回溯判断和操作的困难。
那采么用怎一么个办简?洁有效的方法:设计一个末 尾标记,每次压栈时,先压入末尾标记。
2021/11/25
计算机算法设计与分析
12
用末尾标记的迭代回溯
• Backtrack(Tree T) { • unfinish = true; L.Push(T.root); • while (unfinish || L≠Φ) { • a = L.Pop( ); • if (a is the last mark) backastep( );
• a = L.Pop( );
• if (a == -1) {i– –; a = rec[i]; rec[i]=0;used[a]=0;}
• else if (used[a]==0)
•
{rec[i]=a; used[a]=1;
第5章 回溯法ppt课件
2x3=2
x3=4 x3=2 x3=3
3
5
x4=4 x4=3
8 x4=4
10 13 15 x4=2 x4=3 x4=2
4
6
9
11 14 16
迷宫问题
演示
5.1 回溯法的算法框架
问题的解空间〔1)
1. 解向量:问题的解用向量表示
(x1, x2, …, xk) 模。 2. 约束条件
子树; 5. (2)限界函数:某个函数表达式或关系式。 6. 不真时,用于剪去得不到最优解的子树。 7. 回溯法:具有限界函数的深度优先搜索方法
回溯法的基本思想
1. 以深度优先方式搜索解空间。 2. 开始时,根结点为活结点,也是当前的扩展结点。 3. 对扩展结点,寻找儿子结点: 4. 如找到新结点,新结点成为活结点并成为扩展
子集树 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);
} }
排列树 void backtrack (int t){
if (t>n) output(x); else
1装载问题2批处理作业调度3n后问题401背包问题5最大团问题6图的m着色问题7旅行售货员问题n皇后问题国际象棋中的皇后在横向直向和斜向都能走步和吃子问在nn格的棋盘上如何摆上n个皇后而使她们都不能相互吃掉
第5章 回溯法
上海大学计算机学院
学习要点与要求
• 掌握与理解回溯法的DFS搜索策略与方法
• (1〕掌握递归回溯
《算法设计与分析》-第五章 回溯法
例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),然后以易于搜索 的方式组织解空间,最后用深度优先的方法搜 索解空间,获得问题的解.
第5章 回溯法
6
迭代回溯
采用树的非递归深度优先遍历算法,可将回溯法表示为一个非 递归迭代过程. 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--; } }
第5章 回溯法
1
回溯法
有许多问题,当需要找出它的解集或者要求回答什么 解是满足某些约束条件的最佳解时,往往要使用回溯 法. 回溯法的基本做法是搜索,或是一种组织得井井有条 的,能避免不必要搜索的穷举式搜索法.这种方法适 用于解一些组合数相当大的问题. 回溯法在问题的解空间树中,按深度优先策略,从根 结点出发搜索解空间树.算法搜索至解空间树的任意 一点时,先判断该结点是否包含问题的解.如果肯定 不包含,则跳过对该结点为根的子树的搜索,逐层向 其祖先结点回溯;否则,进入该子树,继续按深度优 先策略搜索.
批处理作业调度
解空间:排列树
private static 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]; public class FlowShop if (f < bestf) { static int n, // 作业数 MyMath.swap(x,i,j); f1, // 机器1完成处理时间 backtrack(i+1); f, // 完成时间和 MyMath.swap(x,i,j); bestf; // 当前最优值 } static int [][] m; // 各作业所需的处理时间 f1-=m[x[j]][1]; static int [] x; // 当前作业调度 f-=f2[i]; static int [] bestx; // 当前最优作业调度 } static int [] f2; // 机器2完成处理时间 }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
if (constraint(t) && bound(t)) backtrack(t + 1); 回溯(的代码); } }2011-8-20
曹来成 11
C
D
3
F
4
G
2
H
4
I O
E
2
J P
3
K
3
M
4
N
2 3
Q
2
L
2
第5章 回溯法
第5章 回溯法
②回溯法搜索排列树的算法描述 void backtrack(int t) { if (t > n) output(x); else for (int i = t; i < n; i++) { swap(x[t], x[i]); //x[i]为当前活结点
而且,事实上不存在穷尽搜索之外的其他算法。
5.1 回溯法的算法框架
5.1.1 问题的解空间 回溯法的解空间
• 明确定义解空 间,至少包含 一个最优解。 1 • 例如:n=3时, 0-1背包问题的 解空间。
2011-8-20 曹来成 4
1
B
A
0
C
1
D
0
E
1
F
0
G
0
I
1
J
0
K
1
L
0 1
M N
0
O
希望将搜索空间减少到尽可能的小。 所采用的组织搜索的技术:回溯法。
第5章 回溯法
第5章 回溯法 public static int maxLoading(int[]ww,int cc,int[] xx){ //修改
算法设计
//类数据成员 public static int n; //集装箱数 public static int[] w; //集装箱重量 public static int c; //第一艘轮船载重量 public static int cw; //当前载重量 public static int bestw; //当前最优载重量 public static int r; //修改:剩余集装箱重量 public static int [] x; //修改:当前解 public static int [] bestx; //修改:当前最优解
曹来成 22
} 2011-8-20
第5章 回溯法
第5章 回溯法
private static void backtrack(int i){ //回溯算法-搜索第i层结点 if(i>n){ //到达叶结点 if(cw>bestw){ bestw=cw; System.out.println("此时最优解是:"); for(int j=1;j<=n;j++){ //修改 bestx[j]=x[j]; //修改 System.out.println(bestx[j]); } } return;
使用剪枝函数: ① 约束函数。 ② 限界函数。
2 2
G
3
C
4 4
H D
3
E
4
F
2
I
3
J
5. 总结:回溯法解题步骤
① 针对所给问题,定义解空间。 2 ② 确定易于搜索的解空间结构。 ③ 深度优先搜索解空间,使用剪枝函数避免无效搜 索。
2011-8-20 曹来成 8
4
K
2011-8-20 曹来成
3
L
2011-8-20 曹来成 10
1
B
A
0
C
1
D
0
E
1
F
0
G
0 1
I J
0 1
K L
0 1
M N
0
O
第5章 回溯法
第5章 回溯法
②回溯法搜索子集树的算法描述 void backtrack(int t) { if (t > n) output(x); else for (int i = 0; i <=1; i++) { 1 H x[t] = i; //x[t] = 0,1
2011-8-20 曹来成 6
1
D E
C
0
1
F
0
G
1
H
2011-8-20
0
I
曹来成 5
1
J
0
K
1
L
0
M
1
N
0
O
1
第5章 回溯法
第5章 回溯法
3. 例2:旅行售货员问题
1 6 3 20 30 5 2 4 10 4 B
1
A
解空间树中: 周游路线—根到叶的路径 叶结点个数为:(n-1)!
4. 避免无效搜索的策略
2011-8-20 曹来成 21
n=ww.length-1; //初始化;n为层数 w=ww; c=cc; cw=0; bestw= 0; x=new int[n+1]; //修改 bestx=xx; //修改 r=0; //修改-初始化 for(int i=1;i<=n;i++) r+=w[i]; //修改 backtrack(1); //计算最优载重量 return bestw;
B
A
②回溯法求解。 ③处理不存在符号三角形的n值。 判断n*(n+1)%4==1 n*(n+1)/2为奇数 ④可行性约束条件-剪去子树。 + (-)个数超过n*(n+1)/4。
0
O
2011-8-20 曹来成 28
1
第1层
0
C
+ + - + + - - - + - x[t]为解空间树的第t层
2011-8-20 曹来成 27
曹来成 24
}
曹来成
23
4
第5章 回溯法
第5章 回溯法
算法复杂性: ①由于bestx可能被更新O(2n) 次, 所以计算时间为: T(n)=O(n2n) 。 ②额外递归栈空间:S(n)=O(n) 。
2011-8-20 曹来成 25
5.3 符号三角形问题
+ + - + - + + + - - - - + ① 第1行有n个符号。 - + + + - ② 两个同号下是“+”,两个 - + + - 异号下是“-”。 - + - ③ 对于给定n,计算有多少 - - + 个不同符号三角形,使其 所含的“+”和“-”的个数 相同。
第5章 回溯法
本章内容
☞5.1 回溯法的算法框架 ☞5.2 装载问题 ☞5.3 符号三角形问题 ☞5.4 n后问题 ☞5.5 图的m着色问题 ☞5.6 旅行售货员问题
第5章 回溯法
第5章 回溯法
引 言
图的遍历算法:①深度优先搜索;②广度 优先搜索。 在许多真实世界的问题中,通过穷尽搜索 数量巨大但有限多个可能性,可以获得一 个解。
A 1 B 1 D 0 1 I J 0 E 0 1 K L
0 C 1 F 0 G 0 1 M N 0 O
2. 什么是排列树? 当所给的问题是确定n个元素满足某种性质的排 列时,相应的解空间树称为排列树。 A 1 排列树通常有n!个叶 B 结点。 2 4 3 遍历排列树需要Ω(n!) 计算时间。 ①旅行售货员问题的解 4 空间是一棵排列树。
1
D
0 第2层1
14个“+”和14个“-”组成的符号三角形
26 2011-8-20 曹来成
1. 问题描述
第5章 回溯法
第5章 回溯法
2. 算法思想
①解空间:第一行n个符号确定1棵完全2叉树。 x[1:n]表示第一行n个符号,x[i]=1(0) 表示第i个符号为“+”(“-”)。
x[1] x[2] x[3] x[4]
2011-8-20 曹来成 14
n
i1
backtrack(t + 1); swap(x[t], x[i]); //回溯 } }
2011-8-20
第5章 回溯法
算法设计
2. 最优 装载方案
①首先将第一艘轮船尽可能装满。 ②将剩余的集装箱装上第二艘轮船。
3. 等价于一个特殊的0-1背包问题
将第一艘轮船尽可能的装 max 满等价于选取全体集装箱 的子集,使该子集中集装 箱的重量之和最接近 c1。
2011-8-20 曹来成 20
②实现的策略
H
设cw为当前载重量,bestw为当前最优载重量,r 为剩余集装箱的重量,则 r 定义:上界函数为cw+r。
j i 1
w
n
j
。
在结点Z处,当cw+r≤ bestw时,将Z的右子树剪 去。 平均情况下检查的结点数减少。
2011-8-20 曹来成 19
第5章 回溯法
第5章 回溯法
第5章 回溯法
//回溯算法-搜索第i层结点 private static void backtrack(int i)
i=1:第1层 ...... 第i层
B1 1 0EFra bibliotekA0
C
算法复杂性: ①计算时间:T(n)=O(2n) 。
0
G
1
F
第i+1层 ...... 第n层
D
② 额外递归栈空间:S(n)=O(n) 。
2011-8-20
System.out.println("当前最优载重量:"+bestw);
//搜索子树 r-=w[i]; //修改 if(cw+w[i]<=c){ //搜索左子树,即x[i]=1 x[i]=1; //修改 cw+=w[i]; backtrack(i+1); cw-=w[i]; } if(cw+r>bestw) //修改 x[i]=0; //修改 backtrack(i+1); //搜索右子树 r+=w[i]; //修改 }2011-8-20