第5章 回溯法

合集下载

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

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

}

}
5.2 回溯法的算法框架
用回溯法搜索子集树的一般解法:
– –
Void backtrack(int t) {
If(t>n) output(x); Else for(i=0;i<=1;i++){ x[t]=i; if(constraint(t)&&bound(t)) backtrack(t+1); }
5.2 回溯法的算法框架
递归回溯的一般解法:
– –
Void traceback(int t) {
If(t>n) output(x); Else for(i=f(n,t);i<=g(n,t);i++){ x[t]=h[i]; if(constraint(t)&&bound(t)) backtrack(t+1); }
5.1 回溯法的基本思想
回溯法(backtracking)是一种系统地搜索问 题解的方法.为实现回溯,首先需要定义一个 解空间(solution space),然后以易于搜索 的方式组织解空间,最后用深度优先的方法搜 索解空间,获得问题的解.
5.1 回溯法的基本思想
回溯法求解的三个步骤: (1)定义一个解空间,它包含问题的解 (2)用易于搜索的方式组织解空间 (3)深度优先搜索解空间,获得问题的解.

回溯法_ppt课件

回溯法_ppt课件

回溯法举例: 若取W= (16,15, 15), P= (40,25, 25), C=30
回溯法举例: [旅行商问题] 在这个问题中,给出一个n 顶点网络(有向 或无向),要求找出一个包含所有n 个顶点的具有最小耗 费的环路。任何一个包含网络中所有n 个顶点的环路被称 作一个旅行(t o u r)。在旅行商问题中,要设法找到一 条最小耗费的旅行。 [分析]图给出了一个四顶点网络。在这个网络中,一些旅 行如下: 1 , 2 , 4 , 3 , 1;1 , 3 , 2 , 4 , 1和1 , 4 , 3 , 2 , 1。 旅行1 , 2 , 4 , 3 , 1的耗费为6 6;而1 , 3 , 2 , 4 , 1的耗费 为2 5;1 , 4 , 3 , 2 , 1为5 9。故1 , 3 , 2 , 4 , 1是该网络 中最小耗费的旅行。
4、形式化描述
设问题的解可表示为n元组(x1, x2,… xn), xisi , si为有限 集,n元组的子组(x1, x2,… xi) i<n 应满足一定的约束条件D. 设已 有满足约束条件的部分解(x1, x2,… xi), 添加xi+1 si+1,若(x1, x2, …xi ,xi+1 )满足约束条件, 则继续添加xi+2 ; 若所有可能的xi+1 si+1 均不满足约束条件,则去掉xi , 回溯到(x1, x2,… xi-1), 添加尚未考 虑过的xi , 如此反复进行,直到(x1, x2,… xk) kn满足所有的约束 条件或证明无解.

第5章 回溯法

第5章 回溯法
9
例如,对于n=3的0/1背包问题,三个物品的重量 为{20, 15, 10},价值为{20, 30, 25},背包容量为 25,从图8.2所示的解空间树的根结点开始搜索, 搜索过程如下:
1 2
1 0 6 10 0 8 不可行解 价值=20 1 11 0 1 14 1
1
0
9 0 13 0 15
不可百度文库解
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
问题的解空间:回溯算法将问题的解表示成一 个n元式(x1,x2,…,xn) 。 xi的取值范围为某个有穷集S。 xi的所有取值范围的组合被称为解空间。

第5章回溯法PPT课件

第5章回溯法PPT课件

放置方案有C
n n
2种,而这个数字是非常庞大的,直接
枚举肯定会超时。
n皇后问题
考虑到皇后攻击的特性,所有的皇后不能同 行、同列,那么不妨我们先人为规定第k个皇 后在第k行,这样的话我们只要给出每个皇后 所处的列号就可以描述皇后的位置了。如图 放置方式就可以被表示为: 3、1、4、2 即第1个皇后在第3列,第2个 皇后在第1列,……
二、回溯的一般描述
一旦某个j元组(x1,x2,…,xj)违反D中仅涉及 x1,x2,…,xj 的一个约束,就可以肯定,以(x1, x2,…,xj)为前缀的任何n元组
(x1,x2,…,xj,xj+1,…,xn)都不会是问题P 的解。
三、回溯的一般步骤
回溯法正是针对这类问题,利用这类问题的 上述性质而提出来的比枚举法效率更高的算 法。
解问题P的最朴素的方法就是枚举法,即对E 中的所有n元组逐一地检测其是否满足D的全 部约束,显然,其计算量是相当大的。
二、回溯的一般描述
对于许多问题,所给定的约束集D具有完备 性。即i元组(x1,x2,…,xi)满足D中仅 涉及到x1,x2,…,xi的所有约束意味着j (j<i)元组(x1,x2,…,xj)一定也满足D 中仅涉及到x1,x2,…,xj的所有约束。
A2 A1
A
跳马问题
2. 当到达A1点后,又有三条线路可以选择, 于是再任意选择一条,到达B1。

第五章 回溯法

第五章  回溯法
搜索引擎中的网络爬虫: 搜索引擎是指根据一定的策略,运用特定的计算机程序从互联网上搜集信
息,对信息进行组织和处理后,为用户提供检索服务,将用户检索相关的
信息展示给用户的系统 搜索引擎的组成: 下载、索引、查询
回溯法引言
搜索引擎中的网络爬虫: 网络爬虫:自动下载互联网中的所有网页
网络爬虫的原理:
5.1 回溯法的算法框架
1
30 6 5 20 4
2 10
推销员问题
问题描述
3
4
每个城市一遍,最后回到住地
的路线,使总的路程最短。 该问题是一个NP完全问题, 有(n-1)!条可选路线 最优解(1,3,2,4,1),最优值25
3 F 4 L
2 C 4 G 3 M 1 3 2 H 4 N
A B D 4 I 2 O 2 J 3 P 4 E 3 K 2 Q
F
w2=15,v2=25 Cr=15,V=25
H
不是最优解 Cr=14 M不可扩展,成为死结点 K V=45 L J F C, <w 返回到 r 3 不可行解 x=(1,0, F没有可扩展结点,成为死结点 0) 返回到 C ,再扩展 C 到达 G I ……
25<50 w3=15,v3=25 不是最 优解 Cr=0,V=50 50>45 x=(0,1,1)
显约束
对分量xi的取值限定。

第5章 回溯法

第5章  回溯法

2. 回溯法的效益分析
应用回溯设计求解实际问题,由于解空间的结构差异,很难精 http://www.gelishfw.com/ http://www.gybcny.com/ http://www.hd8go.com/ http://www.sj93.cn/ http://www.mdwxz88.com/ http://www.oemgc.com/ 确计算与估计回溯产生的结点数,这是分析回溯法效率时遇到的主要 http://www.189288.com/ http://www.hzp580.com http://www.yjoem.com/ http://www.oemdg.com/ http://www.oemfy.com/ http://www.xcdnpx.com/ http://www.yanjigz.com/ http://www.189286.com/ http://www.xcdnpx.com/ http://www.dgxcdn.com http://www.dgxcpx.com/ http://www.xcwxpx.com/ http://www.xunchi-px.com/ http://www.donghuijc.com/http://www.oemfy.com/http://www.0759mz.com/http://www.lczx188.com/ http://www.189287.com/ 困难。 http://www.ystdzkj.com/ http://www.023gree.com/ http://www.glwxz.com/ http://www.023midea.net/ http://www.023chigo.com/http://www.023aux.com/ http://www.023haier.net/ http://www.023xiu.com/ http://www.51xiu.org/ http://www.023vatti.com/ http://www.meidix.com/ http://www.ystdzkj.com/ http://www.ystcode.com/ http://www.hthqdb.com/http://www.023midea.net/bbs/ http://www.ystmach.com/ 回溯法因“适时回头”省去了部分结点的操作与检测,实际操作 http://www.gz-bestally.com/ http://www.gz-bestally.com/ 的结点数通常只有解空间所有结点数的一小部分,这也是回溯法的探 http://cwb1024.blog.163.com/manage/#m=0&t=0 http://blog.sina.com.cn/ 索效率高于枚举的原因所在。 http://www.gz-bestally.com/ www.gzdzbjbw.com/adminbeat/index.asp http://www.ystmach.com/bbs/forum.php 对于元组长度为n的问题,若其状态空间树中结点总数为n!,则 http://www.ystcode.com/bbs/forum.php 回溯算法的最坏情形的时间复杂度可达O(p(n)n!);若其状态空间树 中结点总数为2^n,则回溯算法的最坏情形的时间复杂度可达 O(p(n)2^n),其中p(n)为n的多项式。

算法设计与分析 第2版 第5章-回溯法

算法设计与分析 第2版 第5章-回溯法
第5章 回溯法
5.1 回溯法概述 5.2 求解0/1背包问题
5.3 求解装载问题 5.4 求解子集和问题 5.5 求解n皇后问题 5.6 求解图的m着色问题 5.7 求解任务分配问题 5.8 求解活动安排问题 5.9 求解流水作业调度问题
回溯法概述
5.1.1 问题的解空间
一个复杂问题的解决方案是由若干个小的决策步骤组成的决策序列, 解决一个问题的所有可能的决策序列构成该问题的解空间。
其中:sum记录考虑整数a[i]时前面表达式计算的整数和(初始值 为a[0]),prevadd记录前面表达式中的一个数值(初始值为a[0]),i 从1开始到9结束,如果sum=100,得到一个解。
void fun(char op[],int sum,int prevadd,int a[],int i)
用i扫描数组a,也就是说问题的初始状态是(i=0,x的元素均为0),目标 状态是(i=n,x为一个解)。从状态(i,x)可以扩展出两个状态:
不选择a[i]元素 下一个状态为(i+1,x[i]=0)。 选择a[i]元素 下一个状态为(i+1,x[i]=1)。
void dfs(int a[],int n,int i,int x[])
}
return;
}
op[i]='+'; sum+=a[i]; fun(op,sum,a[i],a,i+1); sum-=a[i];

第五章回溯法

第五章回溯法
1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Sort(W) B←c1; best←c1; i←1 while i≤n do if 装入i后重量不超过c1 then B←B-wi; x[i]←1; i←i +1 else x[i]←0; i←i +1 if B<best then 记录解; best←B Backtrack(i) 回溯 if i=1 then return 最优解 else goto 3

<0,1,1,1>,价值:28,重量:13 <1,0,1,0>,价值:21,重量:12

பைடு நூலகம்最优解:<0,1,1,1>
14
搜索空间

实例:V={12,11,9,8}, W={8,6,4,3}, B=13 搜索空间:子集树, 2n片树叶
<1> <1> <1> <1> <0> <1> <0> <0> <0> <0>
33
求解思路
输入:W=<w1, w2, ..., wn>为集装箱重量,c1和c2为船 的最大载重 算法思想:令第一艘船的载入量为W1 1. 用回溯法求使得c1 -W1达到最小的装载方案 2. 若满足 w1+w2+...+wn -W1 ≤c2 则回答“YES”,否则回答“NO”

第5章 回溯法

第5章 回溯法
◎四川师范大学 计算机科学学院 刘芳 21
( 1≤i<j≤n )
算法设计与分析<<回溯法
例: 排列与组合
计算组合数
Cm
n
1 n 0 m n Cm n n 1 Cm1 Cm1 0 n m
n
Cm
n
m! n !( m n ) !
22
◎四川师范大学 计算机科学学院 刘芳
剪枝函数
25
算法设计与分析<<回溯法
算法的框架
一般来说,非递归回溯(迭代回溯)的算法过程:
1.数据初始化 2. 如果当前状态合法
判断是否到达目标: 是,打印结果;然后换下一种情况 不是,则继续向前探索 否则: 选择下一种可能;
检查是否合法 4.重复上述过程,直至所有情况都搜索完毕,结束。
◎四川师范大学 计算机科学学院 刘芳
11
算法设计与分析<<回溯法
排列树
排列树(Permutation Trees):
当所给问题是确定n个元素满足某种性质的排列时,
相应的解空间树称为排列树。
在排列树中,通常情况下,|S1|=n,|S2|=n-1,…,
解空间为:
|Sn|=1,
(1,2,3,……,n-1,n) (2,1,3,……,n-1,n)
◎四川师范大学 计算机科学学院 刘芳

第5章 回溯法

第5章 回溯法

能走则走,不能走则换一条路走, 无路可走则退一步在重复前面的步骤

迷宫问题实际上是一个心理测试,它反映 了测试者控制心理稳定的能力——在一次 次失败后,是否失去冷静最终陷在迷宫之 中,也正体现了一句诗,“不识庐山真面 目,只缘身在此山中”。
老鼠走迷宫

先选择某一可能的线索进行试探,每一步 试探都有多种方式,将每一方式都一一试 探,如有问题就返回纠正,反复ቤተ መጻሕፍቲ ባይዱ行这种 试探再返回纠正,直到得出全部符合条件 的 答案或是问题无解为止。这种解决问题 的方法就是回溯法。
0-1背包问题
•解空间:子集树 n wi xi c1 •可行性约束函数: i 1 •上界函数:
template<class Typew, class Typep> Typep Knap<Typew, Typep>::Bound(int i)
{// 计算上界
Typew cleft = c - cw; // 剩余容量 Typep b = cp; // 以物品单位重量价值递减序装入物品 while (i <= n && w[i] <= cleft) { cleft -= w[i]; b += p[i]; i++; } // 装满背包 if (i <= n) b += p[i]/w[i] * cleft; return b; }

05回溯法

05回溯法

第5章

回溯法

回溯法也称为试探法,该方法首先暂时放弃关于问题规模大小的限制,并将问题的候选解按某种顺序逐一枚举和检验。当发现当前候选解不可能是解时,就选择下一个候选解;倘若当前候选解除了还不满足问题规模要求外,满足所有其他要求时,继续扩大当前候选解的规模,并继续试探。如果当前候选解满足包括问题规模在内的所有要求时,该候选解就是问题的一个解。

在回溯法中,放弃当前候选解,寻找下一个候选解的过程称为回溯。扩大当前候选解的规模,以继续试探的过程称为向前试探。

回溯法的基本思想:确定了解空间的组织结构后,回溯法就从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。这个开始结点就成为一个活结点,同时也成为当前的扩展结点。在当前的扩展结点处,搜索向纵深方向移至一个新结点。这个新结点就成为一个新的活结点,并成为当前扩展结点。如果在当前的扩展结点处不能再向纵深方向移动,则当前扩展结点就成为死结点。换句话说,这个结点不再是一个活结点。此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。回溯法即

·

96· ACM 程序设计培训教程

以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已没有活结点时为止。

运用回溯法解题通常包含以下三个步骤: (1)针对所给问题,定义问题的解空间; (2)确定易于搜索的解空间结构;

(3)以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索;

5.1〖案例1〗组合问题

找出从自然数1、2、……、n 中任取r 个数的所有组合。 例如n=5,r=3的所有组合为:

第5章 回溯法

第5章 回溯法
7
5.1回溯法的算法框架—基本思想
从例3来看,解空间的确定与我们对问题的描述有关。 如何组织解空间的结构会直接影响对问题的求解效率。这是 因为回溯方法的基本思想是通过搜索解空间来找到问题的可 行解以至最优解。 当所给的问题是从n个元素的集合S中找出满足某种性质 的子集时,相应的解空间树称为子集合树。此时,解空间有 2n 个元素,遍历子集树的任何算法均需Ω(2n)的计算时间。 如例2。 当所给的问题是确定n个元素的满足某种性质的排列时, 相应的解空间树称为排列树,此时,解空间有n!个元素。遍 历排列树的任何算法均需Ω(n!)计算时间,如例1和例3。本 章只讨论具有上两类解空间树的求解问题。
5.2 定和子集问题与0/1背包问题
一、定和子集问题
定和子集问题可以描述成下列的数学问题:确定所有向量满足:
x ( x1 , x2 , , xn )
xi {0,1}, i 1,2, , n
1i n
w x
i
i
M
定和子集问题要求确定所有可行解。 用回溯法求解定和子集问题的过程也即是生成解空间树的一棵子 树的过程,因为,在搜索期间将剪掉不能产生可行解的子树(即不再对 这样的子树进行搜索)。按照前面关于回溯算法的基本思想的说明, 搜索是采用深度优先的路线,算法只记录当前路径。假设当前扩展顶 点是当前路径的k级,也就是说当前路径上, xi , 1 i k 已经确定, 算法要决定下一步搜索目标。此时,有两种情况:

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

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

的子树不可能包含更优的解,剪去。
46
#include <iostream.h> #include <iomanip.h> const int n=4; //图的顶点数
在结点L处记录所找到的周游 路线(1-2-3-4-1),其费用为59
43
回溯法的求解过程

1

2
4
3


3
42
4

2
3
F G H IJ K
4
3
4
23
2
L M N OP Q
在结点M处记录所找到的周游 路线(1-2-4-3-1),其费用为 66>59,所以舍弃该结点。
按上述搜索原则,对整个 排列树进行遍历,共找到 6条可能的周游路径,其 中费用最少的周游路径为 1-3-2-4-1(其费用为25)
for(int i=f(n,t);i<=g(n,t);i++) {
x[t]=h(i);
if(constrain(t)&&bound(t)) {
if(solution(t)) output(x);
else t++;
} else t--;
判断在当前扩展结点处是否 已得到问题的可行解(返回 “真”表示找到可行解)。

第5章回溯法

第5章回溯法

跳马问题
为了判断棋子是否落在棋盘上,我们还必须 知道当前棋子(扩展节点)的位置信息。而 用一系列的方向来表示就比较麻烦,因此, 我们另外使用两个变量来保存当前棋子的坐 标。但这时千万要注意的是一定要在回溯的 时候,修改当前棋子的坐标。
跳马问题
骑士遍历问题的解空间是从左下角到右上角的所有 路径。 解空间的长度是所有路径中最长的路径的长度。 解空间的组织形式是一棵四叉树,一个可行的解就 是从根节点到叶子节点的一条路径。 控制策略则是马必须在棋盘内。
跳马问题
马走日字,当马一开始在黄点时,它下一步 可以到达的点有以下的八个,但由于题目规 定了只能往右走的限制,所以它只能走到四 个绿色点之一。
跳马问题
1. 当马一开始位于左下角的时候,根据规则,
它只有两条线路可以选择(另外两条超出棋 盘的范围),我们无法预知该走哪条,故任 意选择一条,到达A1。 意选择一条,到达A1。
为了描述路径,我们最直接的方法就是记录 路径上所有点的坐标。但比较繁琐。 如果我对马可以走到的四个点都编上号(方 向),那么我们很容易得到每一个方向上两 个坐标和原位置的关系。 同时,四个方向都有了编号,那么在选择路 径的时候也就可以不采用任选的方式了,只 需按照编号依次尝试就可以了。
跳马问题
4 3 2 1
n皇后问题
1
2
3
4
1

第5章 回溯法ppt课件

第5章 回溯法ppt课件
结点。转3; 5. 如找不到新结点,当前结点成为死结点,并回
退到最近的一个活结点,使它成为扩展结点。转3; 6. 搜索继续进行,直到找到所求的解或解空间中已无
活结点时为止。
搜索过程举例--0-1背包问题
• n=3时的0-1背包问题: c=30,w=[16,15,15],v=[45,25,25]
搜索过程举例—旅行商问题TSP
• (2〕理解迭代回溯编程技巧
• 掌握用回溯法解题的算法框架,了解搜索过程
• (1〕子集树算法框架
• (2〕排列树算法框架
• 通过学习典型范例,掌握回溯法的设计策略
• (1〕装载问题
(2〕批处理作业调度〔3〕n后问题
• (4〕0-1背包问题 (5〕最大团问题
• (6〕图的m着色问题〔7〕旅行售货员问题
• G=(V,E),|V|=n
总路径数: 对称情况: (n-1)!/2 非对称情况:(n-1)!
1 30 2
5
6
10
4
3 20 4
回溯法解题步骤
(1)针对所给问题,定义问题的解空间; (2)确定合适的解空间结构; (3)以深度优先方式搜索解空间,并在搜索过程
中用剪枝函数避免无效搜索,直到找到所求的 解或解空间中已无活结点时为止。
}
if (solution(t)) output(x); else t++;

第五章回溯法

第五章回溯法
其解空间由长度为n的0-1向量组成,该 解空间包含了对变量的所有可能的0-1赋 值。当n = 3时,解空间为 { (0, 0, 0 ), (0, 1, 0 ) , ( 0, 0, 1 ),( 1, 0, 0 ), ( 0, 1, 1 ), ( 1, 0, 1 ), ( 1, 1, 0 ), ( 1, 1, 1 ) }。
swap(x[t], x[i]);
}
25
}
5.1 回溯法的算法框架
排列问题的递归算法
template<class T>
void Perm(T list[ ], int k, int m)
{ //生成list [k:m ]的所有排列方式
int i;
if (k == m)
{//输出一个排列方式
for (i = 0; i <= m; i++)
得井井有条的,能避免不必要搜索的穷举 式搜索法。这种以深度优先的方式系统地 搜索问题的解的方法称为回溯法。适用于 解一些组合数相当大的问题。
7
5.1 回溯法的算法框架
5.1 回溯法的算法框架
1. 问题的解空间
问题的解空间应至少包含问题的一个(最优)解。 例如:对于有n种可选择物品的0 - 1背包问题,
1
B
2
3
D
2
4
H
I
3
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

3. 回溯剖析与描述
(1)
回溯求解的问题P: 对于已知的由n元组(x1,x2,„,xn)组成的一个状态空 间E={(x1,x2,„,xn)|xi∈si,i=1,2,„,n},给定关于n元 组中的约束集D,要求E中满足D的全部约束条件的所有n元 组。 对于约束集D具有完备性的问题P,一旦检测断定某个j 元组(x1,x2,„,xj)违反D中仅涉及x1,x2,„,xj的一个约 束,就可以肯定,以(x1,x2,„,xj)为前缀的任何n元组 (x1,x2,„,xj,xj+1,„,xn)都不会是问题P的解,因而就 不必去搜索它们,省略了对部分元素(xj+1,„,xn)的操作 与测试。

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; }
5.4 逐位整除数探索
5.4.1


高逐位整除数
案例提出:
n位高逐位整除数:从其高位开始,高1位能被1整除(显 然), 高2位能被2整除,„,整个n位数能被n整除。 例如10245就是一个5位高逐位整除数。 对于指定的正整数n,共有多少个不同的n位高逐位整除 数?存在n位高逐位整除数的n是否有最大值? 试探索指定的n位高逐位整除数,输出所有n位高逐位整 除数。
5.3 直尺与串珠
5.3.2

数码串珠
案例提出:
在某佛寺遗址考古发掘中意外发现一串奇特的数码珠 串,珠串上共串缀有6颗宝珠,每一宝珠上都刻有一个神 秘的正整数: (1) 6颗宝珠上的整数互不相同。 (2) 这6个整数之和为31,沿珠串相连的若干颗(1— 6颗)珠上整数之和为1,2,„,31不间断,即可以覆盖 区间[1,31]中的所有整数。 请确定珠串上6颗宝珠的整数及其相串的顺序。

(1)
若r=0,即该i位数能被i整除,取标志量t=0;此 时有两个选择: 若已取了n位,则输出一个n位逐位整除数;最后一位增 1后继续。 若不未到n位,则i=i+1继续探索下一位。 (2) 若r≠0,即前i位数不能被i整除,取标志量t=1。 此时a[i]=a[i]+1,即第i位增1后继续。 若增值至a[i]>9,则a[i]=0即该位清“0”后,i=i-1回 溯到前一位。直到第1位增值超过9后,退出循环结束。 该算法可探索并输出所有n位逐位整除数,用s统计解的 个数。 若s=0,说明没有找到n位逐位整除数,输出“无解”。
(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; }
1. 回溯设计要点 设置a,数组,存放求解的高逐位整除数的各位, a[1]存储最高位数字,a[2]存储次高位数字,„, a[n]存储n位数的个位数字。 在a数组中,数组元素a[1]从1开始取值,显然 能被1整除;a[2]从0开始取值,存放第2位数, 前2位即a[1]*10+a[2]能被2整除;„。 为了判别已取i位数能否被i整除,设置j循环: for(r=0,j=1;j<=i;j++) { r=r*10+a[j]; r=r%i; }
2. 回溯实现


回溯法的试探搜索,是一种组织得井井有条的、能避免一些不必 要搜索的枚举式搜索。回溯法在问题的解空间树中,从根结点出 发搜索解空间树,搜索至解空间树的任意一点,先判断该结点是 否包含问题的解;如果肯定不包含,则跳过对该结点为根的子树 的搜索,逐层向其父结点回溯;否则,进入该子树,继续搜索。 从解的角度理解,回溯法将问题的候选解按某种顺序进行枚举和 检验。当发现当前候选解不可能是解时,就选择下一个候选解。 在回溯法中,放弃当前候选解,寻找下一个候选解的过程称为回 溯。若当前候选解除了不满足问题规模要求外,满足所有其他要 求时,继续扩大当前候选解的规模,并继续试探。如果当前候选 解满足包括问题规模在内的所有要求时,该候选解就是问题的一 个解。
5. 回溯法的效益分析
回溯求解过程实质上是遍历一棵“状态树”的过程,只要所激活的状 态结点满足终结条件,应该把它输出或保存。由于在回溯法求解问题时, 一般要求输出问题的所有解,因此在得到并输出一个解后并不终止,还要 进行回溯,以便得到问题的其他解,直至回溯到状态树的根且根的所有子 结点均已被搜索过为止。 回溯法的时间取决于状态空间树上实际生成的那部分问题状态的数目。 对于元组长度为n的问题,若其状态空间树中结点总数为n!,则回溯算法的 最坏情形的时间复杂度可达O(p(n)n!);若其状态空间树中结点总数为2n, 则回溯算法的最坏情形时间复杂度可达O(p(n)2n),其中p(n)为n的多项式。 应用回溯设计求解实际问题,由于解空间的结构差异,很难精确计算 与估计回溯产生的结点数,这是分析回溯法效率时遇到的主要困难。回溯 法实际产生的结点数通常只有解空间所有结点数的一小部分,这也是回溯 法的探索效率大大高于枚举的原因所在。
第5章
教学要求

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

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

1. 回溯的概念
(1) 回溯法(Back track method)有“通用解题法”之美 称,是一种比枚举“聪明”的效率更高的搜索技术。
设置中间变量g:先赋值g=1;若出现某两数字相同(即 a(i)=a(k))或a(1)>a(4),则赋值g=0(重复标记)。 首先从a(1)=1开始,逐步给a(i)(1≤i≤9)赋值,每一 个a(i)赋值从1开始递增至9。直至a(9)赋值,判断: 若i=9,g=1,a(1)*m2*m3+a(4)*m1*m3=a(7)*m1*m2• 时满 同 足,为一组解,用n统计解的个数后,格式输出这组解。 若i<9且g=1,表明还不到9个数字,则下一个a(i)从1开 始赋值继续。 若a(9)=9,则返回前一个数组元素a(8)增1赋值(此时, a(9)又从1开始)再试。若a(8)=9,则返回前一个数组元素 a(7)增1赋值再试。依此类推,直到a(1)=9时,已无法返 回,意味着已全部试毕,求解结束。
a(1) a(4) a (7 ) a(2)a(3) a(5)a(6) a(8)a(9)
1. 回溯设计要点

设置a数组,式中每一□位置用一个数组元素表示:

为避免解重复,设a(1)<a(4),记式中3个分母分别为 m1=a(2)a(3)=a(2)*10+a(3) m2=a(5)a(6)=a(5)*10+a(6) m3=a(8)a(9)=a(8)*10+a(9) 所求分数等式等价于整数等式 a(1)*m2*m3+a(4)*m1*m3=a(7)*m1*•2成立。 m
(1)
部分和的数量 一般地,求解环上有n个整数,其和为s,沿环的部分 和为区间[1-s]上的所有整数。 首先探讨沿圆环6个整数组成部分和的个数。 部分和为1个整数,共6个;相应部分和为5个相连整数 组成,也为6个。 部分和为2个相连整数组成,共6个;相应部分和为4个 相连整数组成,也为6个。 部分和为3个相连整数组成,共6个; 部分和为所有6个相连整数组成,共1个。 因而部分和的个数为:6×5+1=31 共有31个部分和,如果s=31,要覆盖[1,31],意味着 31个部分和没有相同的。 若环上为n个整数,部分和为n(n-1)+1个。
5.2 桥本分数式
案例提出:


日本数学家桥本吉彦教授于1993年10月在我国山东举行的中日美三 国数学教育研讨会上提出以下填数趣题:把1,2,„,9 9个来自百度文库字填入下 这 式的9个方格中(数字不得重复),使下面分数等式成立:

□ □ □ ── + ── = ── □□ □□ □□
桥本教授当即给出了一个解答。这一填数趣题的解是否唯一?如果 不唯一究竟有多少个解?试求出所有解答 (等式左边两个分数交换次 序只算一个解答)。•
(2) 回溯法是一种试探求解的方法:通过对问题的归纳分 析,找出求解问题的一个线索,沿着这一线索往前试 探,若试探成功,即得到解;若试探失败,就逐步往 回退,换其他路线再往前试探。 (3) 回溯法可以形象地概括为“向前走,碰壁回头”,若 再往前走不可能得到解,就回溯,退一步另找线路, 这样可省去大量的无效操作,提高搜索效率。
(2)
建立数学模型 为了确定和为s的n个整数取值及这些整数的分布,使沿 环的部分和能完全覆盖[1,s],建立以下数学模型: 设圆圈的周长为s,在圆圈上划n条刻度,用a数组作标 记。起点为a(0)=0,约定a(1)-a(0)为第1个数,a(2)-a(1) 为第2个数,„,一般地a(i)-a(i-1)为第i个数。因共n个 数,显然刻度a(n)=s且与起点a(0)重合。 因n个数中至少有一个数为1(否则不能覆盖1),不妨 设第1个数为1,即a(1)=1。 n个数的每一个数都可以与(约定顺时针方向)相连的1, 2,„,n-1个数组成部分和。为构造部分和方便,定义 a(n+1)与a(1)重合,即 a(n+1)=s+a(1);定义a(n+2)与 a(2)重合,即a(n+2)=s+a(2); „;最后有a(2n-1)与 a(n-1)重合,即a(2n-1)=s+a(n-1)。
(3)
判别完全覆盖 设置b数组存储部分和,变量u统计b数组覆盖 区间[1,s]中数的个数。若u=s-1,(s本身显然 覆盖,除去不计),即完全覆盖。 (4) 取数与回溯 若i<n-1,i增1后a[i]=a[i-1]+1后继续探索。 当i>1时a(i)增1继续,至a(i)=s-n+i时回溯。 变量s与n的值从键盘输入。运行程序时,选择s 是从n(n-1)+1开始,逐减取值输入,最先所得解 为对应n的s最大值。然后再从这些解中选取没有 相同整数的解。

2. 回潮设计描述
i=1;a[1]=1;s=0; while


(1) {g=1;for(k=i-1;k>=1;k--) if(a[i]==a[k]) {g=0;break;} // 两数相同,标记g=0 if(i==9 && g==1 && a[1]<a[4]) { m1=a[2]*10+a[3];m2=a[5]*10+a[6];m3=a[8]*10+a[9]; if(a[1]*m2*m3+a[4]*m1*m3==a[7]*m1*m2) // 判断等式 {s++;printf(“(%2d) ”,s); } // 输出一个解 } if(i< 9 && g==1) {i++;a[i]=1;continue;} // 不到9个数继续 while(a[i]==9 && i>1) i--; // 往前回溯 if(a[i]==9 && i==1) break; else a[i]++; // 至第1个数为9结束 }
相关文档
最新文档