算法设计与分析第6章回溯与分支限界

合集下载

回溯法和分支限界法解决0-1背包题(精)[精品文档]

回溯法和分支限界法解决0-1背包题(精)[精品文档]

0-1背包问题计科1班朱润华 2012040732方法1:回溯法一、回溯法描述:用回溯法解问题时,应明确定义问题的解空间。

问题的解空间至少包含问题的一个(最优)解。

对于0-1背包问题,解空间由长度为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)}然后可将解空间组织成树或图的形式,0-1背包则可用完全二叉树表示其解空间给定n种物品和一背包。

物品i的重量是wi,其价值为vi,背包的容量为C。

问:应如何选择装入背包的物品,使得装入背包中物品的总价值最大?形式化描述:给定c >0, wi >0, vi >0 , 1≤i≤n.要求找一n元向量(x1,x2,…,xn,),xi∈{0,1}, ? ∑ wi xi≤c,且∑ vi xi达最大.即一个特殊的整数规划问题。

二、回溯法步骤思想描述:0-1背包问题是子集选取问题。

0-1 背包问题的解空间可以用子集树表示。

在搜索解空间树时,只要其左儿子节点是一个可行节点,搜索就进入左子树。

当右子树中有可能含有最优解时,才进入右子树搜索。

否则,将右子树剪去。

设r是当前剩余物品价值总和,cp是当前价值;bestp是当前最优价值。

当cp+r<=bestp时,可剪去右子树。

计算右子树上界的更好的方法是将剩余物品依次按其单位价值排序,然后依次装入物品,直至装不下时,再装入物品一部分而装满背包。

例如:对于0-1背包问题的一个实例,n=4,c=7,p=[9,10,7,4],w=[3,5,2,1]。

这4个物品的单位重量价值分别为[3,2,3,5,4]。

以物品单位重量价值的递减序装入物品。

先装入物品4,然后装入物品3和1.装入这3个物品后,剩余的背包容量为1,只能装0.2的物品2。

由此得一个解为[1,0.2,1,1],其相应价值为22。

第六章 分支限界法.ppt

第六章 分支限界法.ppt
得到的解 继续搜索
13
单源最短路径问题
1. 问题描述
下面以一个例子来说明单源最短路径问题:在下 图所给的有向图G中,每一边都有一个非负边权。要 求图G的从源顶点s到目标顶点t之间的最短路径。
14
单源最短路径问题
1. 问题描述
下图是用优先队列式分支限界法解有向图G的 单源最短路径问题产生的解空间树。其中,每一个结 点旁边的数字表示该结点所对应的当前路长。
// 取下一扩展结点
i++;}
// 进入下一层
}
26
装载问题
3. 算法的改进
结点的左子树表示将此集装箱装上船,右子树 表示不将此集装箱装上船。设bestw是当前最优解; ew是当前扩展结点所相应的重量;r是剩余集装箱 的重量。则当ew+rbestw时,可将其右子树剪去, 因为此时若要船装最多集装箱,就应该把此箱装 上船。
(2)回溯求解TSP也是盲目的(虽有目标函数,也 只有找到一个可行解后才有意义)
7
解空间树的动态搜索
分支限界法首先确定一个合理的限界函数,并根据限 界函数确定目标函数的界[down, up]; 然后按照广度优先策略遍历问题的解空间树,在某一 分支上,依次搜索该结点的所有孩子结点,分别估算 这些孩子结点的目标函数的可能取值(对最小化问题, 估算结点的down,对最大化问题,估算结点的up)。 如果某孩子结点的目标函数值超出目标函数的界,则 将其丢弃(从此结点生成的解不会比目前已得的更 好),否则入待处理表。
A->E->Q->M
21
单源最短路径问题
Dijakstra算法和分支限法在解决该问题的异同:
优先队列式分支限界法的搜索方式是根据活结点的优先级确 定下一个扩展结点。结点的优先级常用一个与该结点有关的 数值p来表示。最大优先队列规定p值较大的结点点的优先级 较高。在算法实现时通常用一个最大堆来实现最大优先队列, 体现最大效益优先的原则。类似地,最小优先队列规定p值 较小的结点的优先级较高。在算法实现时,常用一个最小堆 来实现,体现最小优先的原则。采用优先队列式分支定界算 法解决具体问题时,应根据问题的特点选用最大优先或最小 优先队列,确定各个结点点的p值。

算法分析与设计(第2版)分支限界法

算法分析与设计(第2版)分支限界法

(1)求解目标:回溯法的求解目标是找出解空间树中满 足约束条件的所有解,而分支限界法的求解目标则是找出 满足约束条件的一个解,或是在满足约束条件的解中找出 在某种意义下的最优解。 (2)搜索方式的不同:回溯法以深度优先的方式搜索解 空间树,而分支限界法则以广度优先或以最小耗费优先的 方式搜索解空间树。
2. 分支限界法基本思想
分支限界法常以广度优先或以最小耗费(最大效益) 优先的方式搜索问题的解空间树。在分支限界法中,每一 个活结点只有一次机会成为扩展结点。活结点一旦成为扩 展结点,就一次性产生其所有儿子结点。在这些儿子结点 中,导致不可行解或导致非最优解的儿子结点被舍弃,其 余儿子结点被加入活结点表中。此后,从活结点表中取下 一结点成为当前扩展结点,并重复上述结点扩展过程。这 个过程一直持续到找到所需的解或活结点表为空时为止。
第6章 分支限界法
本章主要知识点
• 6.1 分支限界法的基本思想

• • • •
6.2 单源最短路径问题
6.3 装载问题 6.4 布线问题 6.5 6.6 0-1背包问题 最大团问题

• •
6.7
6.8 6.9
旅行售货员问题
电路板排列问题 批处理作业调度
6.1 分支限界法的基本思想
1. 分支限界法与回溯法的不同
2. 算法思想
解单源最短路径问题的优先队列式分支限界法用一 极小堆来存储活结点表。其优先级是结点所对应的当前 路长。 算法从图G的源顶点s和空优先队列开始。结点s被扩 展后,它的儿子结点被依次插入堆中。此后,算法从堆 中取出具有最小当前路长的结点作为当前扩展结点,并 依次检查与当前扩展结点相邻的所有顶点。如果从当前 扩展结点i到顶点j有边可达,且从源出发,途经顶点i再 到顶点j的所相应的路径的长度小于当前最优路径长度, 则将该顶点作为活结点插入到活结点优先队列中。这个 结点的扩展过程一直继续到活结点优先队列为空时为止。

第6章 分支限界法

第6章 分支限界法

6.3 装载问题
1. 问题描述
• 有一批共个集装箱要装上 2 艘载重量分别为 C1 和C2的轮船,其中集装箱i的重量为wi,且
w
i 1
n
i
c1 c2
• 装载问题要求确定是否有一个合理的装载方案 可将这个集装箱装上这2艘轮船。如果有,找出 一种装载方案。 • 如果一个给定装载问题有解,则采用装载策略
最短路径问题关键部分算法
while (true){ // 搜索问题的解空间 for (int j=1;j<=n;j++) if(c[E.i][j] <max && E.length+cE.i][j] < dist[j]) { // 顶点i到顶点j可达,且满足控制约束 dist[j]=E.length+c[E.i][j]; //修正数值
bestx[j] = (bestE.LChild) ? 1 : 0; bestE = bestE.parent; }
学习要点
理解分支限界法的剪枝搜索策略 掌握分支限界法的算法框架,会描述队列变化
(1)队列式(FIFO)分支限界法
(2)优先队列式分支限界法 :会确定优先级
通过应用范例学习分支限界法的设计策略
掌握两类例子每类2个例子:子集树、排列树
分支限界法与回溯法
(1)求解目标:基本相同 回溯法:通过回溯找出满足约束条件的所有解或最 优解 分支限界法:找出满足约束条件的一个解,或是在 满足约束条件的解中找出在某种意义下的最优解 (2)搜索方式:不同
3. 约束条件 1)显式约束:对分量xi的取值限定。
2)隐式约束:为满足问题的解而对不同分量之 间施加的约束。 4. 解空间:对于问题的一个实例,解向量满足显式 约束条件的所有多元组,构成了该实例的一个解空间。

算法设计与_第6章_分支限界法

算法设计与_第6章_分支限界法

两个比较值


பைடு நூலகம்
对于一棵解空间树上的每一个节点所代表的部分解, 要计算出通过这个部分解繁衍出的任何解在目标函 数上的最佳值边界 目前求得的最佳解的值

算法会为每一节点x计算一个界,任何可能在以x 为根的子树中生成的结点所给出的解,其值都不 可能超出这个界. 分支限界法的主要思想


如果边界值不能超越最佳解,这个节点就是一个没有 希望的节点.
8
分支限界法的基本思想

实例——8-拼块游戏问题
输入: 具有8 个编号小方块的魔方
输出: 移动系列, 经过这些移动, 魔方达到目标状态
2 1 7
8 6
3 4 5
1 8 7
2 6
3 4 5
初始状态
目标状态
9
分支限界法的基本思想

FIFO队列式分支限界法
. 2 3 1 8 4 7 6 5 2 . 3 1 8 4 7 6 5 1 2 3 . 8 4 7 6 5 2 8 3 1 . 4 7 6 5 1 2 3 7 8 4 . 6 5
2
6
2 8 3 1 6 4 7 5 2 8 3 1 4 7 6 5
3
4
L=(3,2,4)
5
5
6
5
7
6
L=(5,6,2,4,7)
8
6
8 3 2 1 4 7 6 5
9
7
2 8 3 10 2 3 7 1 4 1 8 4 6 5 5 7 6 5 12 1 2 3 8 4 5 7 6 5
11 2 3 1 8 4 7 7 6 5
Queue Q; Q.add(-1); while (i != n+1) {

大学_计算机算法设计与分析第4版(王晓东著)课后答案下载

大学_计算机算法设计与分析第4版(王晓东著)课后答案下载

计算机算法设计与分析第4版(王晓东著)课后答
案下载
计算机算法设计与分析第4版内容简介
第1章算法概述
1.1 算法与程序
1.2 算法复杂性分析
1.3 NP完全性理论
算法分析题1
算法实现题1
第2章递归与分治策略
2.1 递归的概念
2.2 分治法的基本思想
2.3 二分搜索技术
2.4 大整数的乘法
2.5 Strassen矩阵乘法
2.6 棋盘覆盖
2.7 合并排序
2.8 快速排序
2.9 线性时间选择
2.10 最接近点对问题
第3章动态规划
第4章贪心算法
第5章回溯法
第6章分支限界法
第7章随机化算法
第8章线性规划与网络流
附录A C++概要
参考文献
计算机算法设计与分析第4版目录
本书是普通高等教育“十一五”__规划教材和国家精品课程教材。

全书以算法设计策略为知识单元,系统介绍计算机算法的设计方法与分析技巧。

主要内容包括:算法概述、递归与分治策略、动态规划、贪心算法、回溯法、分支限界法、__化算法、线性规划与网络流等。

书中既涉及经典与实用算法及实例分析,又包括算法热点领域追踪。

为突出教材的`可读性和可用性,章首增加了学习要点提示,章末配有难易适度的算法分析题和算法实现题;配套出版了《计算机算法设计与分析习题解答(第2版)》;并免费提供电子课件和教学服务。

回溯分支限界

回溯分支限界
Feasible (solution), Infeasible (solution), Partial Solution, Optimal Solution, Branch, Bound (tight), Traverse, Backtracking, Prune, DFS, BFS, Frontier Search, Initial solution, Relax
• Give each of the arcs an arc number, from 1 to m, as identification.
• The branching within each stage corresponds to the decision of either adding a certain arc to the solution arc set or not.
• introduce an arc-oriented branch and bound method, branching by using an arc or not.
A Binary Search Tree
• Define an m-stage binary search tree for problem with n nodes, where, for complete graph problem, m equals the number of pairs of nodes.
• Define traveling along left branch represents for choosing an arc and traveling along right branch represents for not choosing an arc.

第6章-限界剪枝法

第6章-限界剪枝法

07 章
其他以i为起点和以j为终点的边;

将Aj1置为∞,以避免选入(j,1);
界 剪 枝
如此得到的矩阵就是x的归约矩阵Ax, 归约于Ax的归约数为rx,则定义:
法 ~C(x) = ~C(y)+rx
归约于矩阵Ax的归约数rx是指Ax
相对于Ay的归约数的增量——由
第 于取消了某些边的选择,可能会
07 章

为耗费估计函数;
界 剪
1 3 4 15
1234

2
5 12
5678

7 6 11 14
9 10 11 12
8 9 10 13
13 14 15
最小耗费搜索法
最小耗费搜索法

15迷问题
07
布局结构描述

布局结点不仅包括数字位的分布情况,还包括已经推演的步 数和与目标布局的差异,以及指向父结点的指针。
~C(e)≤~C(x),

若e是回答结点,则
对x分枝中的任一解结点y,有
输出解或求解路径,求解结~束C(;x)≤C(y)=D(y),

否则
又知:~C(e)=C(e)=D(e),则

检查e的所有子结点x: D(e)≤D(y)。

若x满足约束条件,则

计算~C(x),并将x入队;

记录搜索路径;

~C(y)>U,则由C(x)的单调性和~C(x)是C(x)的下界可知:

U<~C(y)≤C(y)≤C(x) x为解结点

即,在y的子树中不会包含所要求的最优解结点x*,因而可以

放弃对该子树的搜索。

回溯法和分支限界法

回溯法和分支限界法

7
子集树与排列树
遍历子集树需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!)计算时间
1
问题的解空间
• 问题的解向量:回溯法希望一个问题的解能够表示成一个n
• • •
元式(x1,x2,…,xn)的形式。 显约束:对分量xi的取值限定。 隐约束:为满足问题的解而对不同分量之间施加的约束。 解空间:对于问题的一个实例,解向量满足显式约束条件的 所有多元组,构成了该实例的一个解空间。
注意:同一个问题可以有多种表示,有些表示方法更简单, 所需表示的状态空间更小(存储量少,搜索方法简单)。
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--; }
• 扩展结点:一个正在产生儿子的结点称为扩展结点 • 活结点:一个自身已生成但其儿子还没有全部生成的节点 • •
称做活结点 死结点:一个所有儿子已经产生的结点称做死结点 深度优先的问题状态生成法:如果对一个扩展结点R,一 旦产生了它的一个儿子C,就把C当做新的扩展结点。在 完成对子树C(以C为根的子树)的穷尽搜索之后,将R 重新变成扩展结点,继续生成R的下一个儿子(如果存在) 宽度优先的问题状态生成法:在一个扩展结点变成死结 点之前,它一直是扩展结点 回溯法:为了避免生成那些不可能产生最佳解的问题状 态,要不断地利用限界函数(bounding function)来处 死那些实际上不可能产生所需解的活结点,以减少问题 的计算量。具有限界函数的深度优先生成法称• • • • • • • • • • • • • • • • • • • • • • •

回溯与分支限界算法设计

回溯与分支限界算法设计

算法设计与分析实验报告1.骑士游历问题(采用回溯法):在国际象棋的棋盘(8行×8列)上放置一个马,按照“马走日字”的规则,马要遍历棋盘,即到达棋盘上的每一格,并且每格只到达一次。

若给定起始位置(x0,y0),编程探索出一条路径,沿着这条路径马能遍历棋盘上的所有单元格。

2. 行列变换问题(采用分支限界法):给定两个m n方格阵列组成的图形A和图形B,每个方格的颜色为黑色或白色,如下图所示。

行列变换问题的每一步变换可以交换任意2行或2列方格的颜色,或者将某行或某列颠倒。

上述每次变换算作一步。

试设计一个算法,计算最少需要多少步,才能将图形A变换为图形B。

图形A图形B2. 行列变换问题的程序:package .t8;import java.util.LinkedList;import java.util.Scanner;class graph{static int sour, dest;//sour是图形的初始整数,dest是图形的目的整数static int ans[]=new int[1<<16];//静态变量(即全局变量),用于存放图形变换的路径int m=4,n=4,x;int row[]=new int[4];int col[]=new int[4];void setx(int x){this.x=x;}int getx(){return this.x;}void rowx(){//将一个整数划分成四行二进制int y;for(int i=0;i<m;i++){y=1;row[i]=0;for(int j=0;j<n;j++){if((x&1)!=0) //如果x的最低位是1row[i]|=y;y<<=1;x>>=1;}}}}实例:总结实验心得体会:掌握回溯法解决问题的一般步骤。

学会使用回溯法解决实际问题。

掌握分支限界法解决问题的基本思想。

第6章__分支限界法

第6章__分支限界法
20
算法的改进

节点的左子树表示将此集装箱装上船,右 子树表示不将此集装箱装上船。

设bestw是当前最优解;ew是当前扩展结点所相 应的重量;r是剩余集装箱的重量。则当 ew+rbestw时,可将其右子树剪去,因为此时 若要船装最多集装箱,就应该把此箱装上船。

另外,为了确保右子树成功剪枝,应该在 算法每一次进入左子树的时候更新bestw的 值。
28
优先队列式分支限界法

在优先队列式分支限界法中,一旦有一个叶结 点成为当前扩展结点,则可以断言该叶结点所 相应的解即为最优解。此时可终止算法。 最大优先级队列中的活节点都是互相独立的, 因此每个活节点内部必须记录从子集树的根到 此节点的路径。 一旦找到了最优装载所对应的叶节点,就利用 这些路径信息来计算x 值。
分支限界法
1
提纲
分支限界法的基本思想 装载问题 布线问题 0-1背包问题 小结

2
提纲
分支限界法的基本思想 装载问题 布线问题 0-1背包问题 小结

3
分支限界法的基本思想

分支限界法与回溯法的不同

求解目标

回溯法:所有解 分支限界法:找出满足约束条件的一个解,或是满 足约束条件的解中找出在某种意义下的最优解。 回溯法:深度优先搜索解空间树 分支限界法:广度优先或以最小耗费(最大收益)优先 的方式搜索解空间树。
25
构造最优解
算法EnQueue做如下修改: void EnQueue(…..) {// 如不是叶节点,向Q中添加一个i 层、重量为wt的活节点 // 新节点是E的孩子。当且仅当是左孩子时,ch为true。 if (i == n) // 叶子 { if (wt == bestw) // 目前的最优解 { bestE = E; bestx[n] = ch;} return; } QNode<T> *b; // 不是叶子, 添加到队列中 b = new QNode<T>; b->weight = wt; b->parent = E; b->LChild = ch; Q.Add(b); }

动态规划法-回溯法-分支限界法求解TSP问题实验报告

动态规划法-回溯法-分支限界法求解TSP问题实验报告
{
for(int i=1;i<=n;i++)
vis[i]=x[i];
ans=cur+mp[x[n-1]][x[n]]+mp[x[n]][1];
}
}
else
{
for(int i=t;i<=n;i++)
{
if(mp[x[t-1]][x[i]]!=-1&&(cur+mp[x[t-1]][x[i]]<ans||ans==-1))
一般情况下,假设当前已确定的路径为U=(r1,r2,…,rk),即路径上已确定了k个顶点,此时,该部分解的目标函数值的计算方法(限界函数)如下:
Lb=(2∑c[ri][r(i+1)]+∑ri行不在路径上的最小元素+∑ri行最小的两个元素)/2
算法设计
输入:图G=(V,E)
输出:最短哈密顿回路
1、根据限界函数计算目标函数的下界down;采用贪心法得到上界up;
算法设计
输入:图的代价矩阵mp[n][n]
输出:从顶点0出发经过所有顶点一次且仅一次再回到顶点0的最短路径长度
1.初始化第0列(动态规划的边界问题)
for(i=1;i<n;i++)
dp[i][0]=mp[i][0]
2.依次处理每个子集数组x[2^n-1]
for(i=1;i<n;i++)
if(子集x[j]中不包含i)
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
using namespace std;

第6章分支限界法

第6章分支限界法

堆的定义: 若n个元素的序列{a1 a2 … an} 满足 ai ≤ a2i ai ≤ a2i+1 或 ai ≥ a2i ai ≥ a2i+1
则分别称该序列{a1 a2 … an}为小根堆 和大根堆。 从堆的定义可以看出,堆实质是满足如下性质的完 全二叉树: 二叉树中任一非叶子结点均小于(大于)它的孩子结点
问题定义:在n×n的国际象棋棋盘上摆下n个皇后,使所有 的皇后都不能攻击到对方,找出所有符合要求的情况。 分析: n后问题的解空间树是一棵排列树,解与解之间不存在优 劣的分别。直到搜索到叶结点时才能确定出一组解。 采用回溯法可以系统地搜索问题的全部解。
分支限界法的基本思想
既可以采用回溯法也可以采用分支限界法解决
4
B G H I H I E J C D
(0,0)
0
D
0
E
0
(5,15)
F
0
1
G M
(0,0)
1
1
1
0
H
10 0
I
J
15 10 5
K
0
L
N
15 0
O
15 10 20 5
B C D E F G I K L M N O
20 0 35 20 15 0 35 20 40 15 25 0 当前最优解 当前最优解
举例:0-1背包问题
n=3时0-1背包问题的一个实例:w=[16, 15, 15],p=[45, 25, 25],
的问题 — 0-1背包问题
问题定义:给定若干物品的重量和价值,以及 一个背包的容量上限。求出一种方案使得背包 中存放物品的价值最高。
分析:0-1背包问题的解空间树是一棵子集树, 所要求的解具有最优性质。

算法分析与设计-第六章分支限界法

算法分析与设计-第六章分支限界法
➢ 队列式分支限界法:
[A] B, C => B, C [B, C] D, E => E [C, E] F, G => F, G [E, F, G] J, K => K(45) [1,0,0] [F, G] L, M =>L(50) [0, 1, 1] M(25) [G] N, 0 =>N(25), O(0)
if (Ew == -1) { // 同层结点尾部
if (Q.IsEmpty()) return bestw;
Q.Add(-1); // 同层结点尾部标志
Q.Delete(Ew); // 取下一扩展结点
i++;}
// 进入下一层 } }
6.3 装载问题
6.3 装载问题
3. 算法的改进
节点的左子树表示将此集装箱装上船,右子树表示不将 此集装箱装上船。设bestw是当前最优解;ew是当前扩展 结点所相应的重量;r是剩余集装箱的重量。则当 ew+rbestw时,可将其右子树剪去,因为此时若要船装 最多集装箱,就应该把此箱装上船。
➢ 可用剪枝函数加速搜索

1A0
B
C
D
E
F
G
H I J K LMNO
6
四、旅行售货员问题
➢ 队列式分支限界法:
[A] B, C, D [B, C, D] E, F [C, D, E, F] G, H [D, E, F, G, H] I, J [E, F, G, H, I, J] K(59) [1,2,3,4] [F, G, H, I, J] L(66) [G, H, I, J] M(25) [1, 3, 2, 4] [H, I, J] 1-3-4(26) [I, J] O(25) [J] P(59)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

算法设计与分析目录算法设计与分析 (1)第6章回溯与分支限界 (3)6.1回溯法的设计技术 (3)6.2用回溯法求解装载问题 (7)6.3用回溯法求解n皇后问题 (9)6.4用回溯法求解0-1背包问题 (11)6.5用回溯法求解旅行商问题 (13)6.6 分支限界法的设计技术 (15)6.7 用分支限界法求问题的解 (15)本章小结 (15)参考文献 (16)第6章回溯与分支限界内容导读回溯法(Back Tracking Algorithm)与分支限界法(Branch and Bound Algorithm)都是基本的算法设计策略,属于树的搜索技术的范畴。

在使用这两种算法求解问题前,均需要把解空间规划成一棵解空间树,并且在求解过程中使用剪枝策略来提高搜索效率。

回溯法也称试探法,可以把它看成是一个在约束条件下对解空间树进行深度优先搜索的过程,并在搜索过程中剪去那些不满足条件的分支。

当用回溯法搜索到解空间树的某个结点时,如果发现当前路径不满足约束条件或不是历史最优时,则放弃对该结点的子树的搜索,并逐层向其祖先结点返回。

否则,进入该结点的子树,继续进行深度优先搜索。

实质上,这是一个先根遍历解空间树的过程,只是这个棵树不是遍历前预先建立的,而是隐含在遍历过程当中的。

分支限界法则是以最小代价优先的方式在解空间树上进行搜索,它可以找出满足问题约束的一个可行解,或者是从满足约束条件的可行解中找出一个使得目标函数达到极值的最优解。

这里的可行解在搜索树中表现为一条由根到叶子结点的路径,这条路径上权值的和为可行解的值。

其中,最优解就是使可行解的值达到最优的那条路径。

分支限界算法的核心思想就是增加更多的约束条件,剪掉更多的分支,当对当前的树结点进行扩展时,一次性产生其所有儿子结点,并抛弃那些不可能产生可行解或最优解的结点,即剪枝;对于留下的儿子结点,计算一个函数值(限界),然后选取一个最有利的结点继续进行扩展,使得搜索朝着最优解的分支推进。

重复这个过程直到找到最优解或没有可扩展的结点。

6.1回溯法的设计技术6.1.1算法思想回溯算法是一种有组织的系统最优化搜索技术,用它可以求解问题的所有解、一组解或一个解。

例如经典的n皇后问题,它是指在一个n*n的棋盘上放置n个不能够互相攻击的皇后的问题。

按照国际象棋的规则,任意两个皇后之间不能处在同一行、同一列和同一斜线上,否则皇后就可以攻击与之处在同一行、同一列或同一斜线上的棋子。

如图6-1所示为一个4个皇后的合理摆放格局。

那么,如何找到这样一个格局或者找到所有满足要求的解呢?图6-1 4皇后的一个格局可以采用这样一种策略:设每一行的棋格为一层,用x i代表第i层皇后的摆放位置(共有4个值,表示棋格的列),那么,4皇后问题可以描述为一个4元组(x1,x2,x3,x4),这4个元素代表每一层皇后的摆放位置(列),当它们都取得满足题目要求值时,则得到一组解。

图6-2展示了4皇后问题的求解过程:(1)第一层,由于没有其它皇后,4个摆放位置均可摆放,x1的值可取1、2、3、4。

(2)第二层,可针对于x1的每一个取值进行扩展,为第二层皇后选择位置,即给x2赋值。

那么,针对于x1=1,x2有4个位置可以选择。

尝试摆放的过程如下:x2=1的位置,不能摆放,因为两个皇后在同一列上,因此,不对其继续进行扩展,回退到上一层进行重新摆放。

x2=2的位置不能摆放,因为两个皇后在同一对角线上,再次回退到上一层。

尝试在x2=3位置摆放,此时,满足要求,第二层摆放成功,可沿这分支继续进行扩展。

(3)第三层,沿x2=3的位置进行扩展,给x3进行赋值。

由图6-2可知,由这一分支而下的所尝试均不满足要求,最终回退至第二层,它同时也宣告了x2=3摆放的失败,即沿这一分支不可能找到解,则再回溯到第一层,重新摆放皇后、为x2取值,让x2=4,满足要求,沿此分支进行扩展。

(4)第三层,沿x2=4尝试向下扩展,给x3取值,方法与上面描述的相同,尝试成功,则继续向下搜索,不成功则返回上一层,给x3重新取值……,依此,直到第4层摆放完毕,且x1、x2、x3、x4均得到满足要求的值,则找到一组解,如图6-2中的X(2,4,1,3)。

通过上述不断的测试,可以把n皇后问题的所有解全部找出来。

这个求解策略就是回溯法。

图6-2 4皇后问题的回溯过程采用回溯法求解问题,需要将问题的解表达为n元组(X1,…,X i,…X n),其中X i选自有限集S i,当选出一组值X=(x1,…,x i,…x n)能够使评价函数P(x1,…,x i,…x n) 满足问题的某种约束条件或到达极值,则X为此问题的解或最优解。

这里4皇后问题的评价函数就是对“同一行、同一列和同一斜线”的判断。

若采用枚举搜索技术,则需要枚举出所有可能的n元组,并用P(X1,…,X i,…X n)去一一评价,所需的时空复杂性一般令人难以接受。

回溯法可以看作枚举搜索技术的改进,它通过剪枝技术(参看(2)、(3)、(4)中的回溯),可以避免搜索所有可能的解。

回溯法的基本策略是每次只考虑一个分量,逐次扩大建立n元组,并随时用评价函数P i(X1,…,X i,…X n)去判断正在形成的n元组是否有成功的希望,一旦确定部分元组(X1,…,X i)不能求出解时,则立即停止这种搜索,“剪掉”以当前结点为根的分枝,并逐次向上一个分量回溯,然后向其它分支继续探索。

上述搜索过程通常会形成一棵包含问题解的树,称之为解空间树。

树的每一个结点表示问题求解过程中的一个状态,从树根到其它结点的全部路径构成了问题的解空间,每条自根到叶子的路径代表了解空间中的一个元组,所有满足约束条件的元组构成了问题的解集合,而约束描述了X i彼此相关的情况。

解空间树是在求解的过程中,一个结点一个结点逐步生成的,为了更好的理解和讲解算法,可以将这些结点分为活结点、扩展结点和死结点三类。

在解空间树中那些已经生成了部分子结点,但还没有全部生产完毕的结点叫做活结点;当前正在生成子结点的活结点叫做扩展结点;那些不再进一步扩展或已经将全部子结点生成完毕的结点叫做死结点。

6.1.2算法框架通过4皇后问题生成解的过程,可以了解到回溯算法是从开始结点进行深度优先搜索,并通过剪枝技术提高搜索效率的算法策略,其过程可描述如下:(1)开始结点是一个活结点,也是一个扩展结点;(2)如果能从当前的扩展结点移动到一个新的结点,那么这个新结点将变成一个活结点和可扩展结点,旧的扩展结点仍是一个活结点。

(3)如果不能移动到一个新结点(已经找到一个解或违反约束的情况),当前的扩展结点就变成了一个死结点,便只能返回到最近被考察的活结点(回溯),这个活结点就变成了新的扩展结点。

(4)当找到了最优解或者没有活结点的时候(回溯尽了所有的活结点),搜索过程结束。

根据这一描述过程,可以得到回溯算法策略的框架:输入:n6.1.3回溯算法的适用条件回溯算法需要满足多米诺性质,才能得到正确的应用。

多米诺性质设向量X i=<x1, x2,…,x i >,X i⊆X,X=< x1, x2,…,x i,…,x n >,将X i输入评价函数P,可以得到X i的一组特征值P(Xi),取X i+1=<x1, x2,…,x i, x i+1 >,X i+1⊆X,则P(Xi+1)真蕴涵P(Xi),即P(X i+1)→P(X i) i∈(0,n)其中,n代表解向量的维数。

【例6-1】求满足下列不等式的所有整数解:5x1+4x2-x3≤10 1≤x i≤3 i=1, 2, 3解:令X i=<x1, x2,…,x i>,P(X i)为对Xi的评估,判断其Xi是否满足不等式,即P(Xi) ≤10。

依据题目可知,本例中向量为一个三元组< x1, x2, x3>,其搜索过程如图6-3所示。

x1x2x3图6-3 例6-1的解空间树注意图6-3的虚线部分,当x1=1、x2=2时,P(x1,x2)= 5x1+4x2=5*1+4*2=13>10,不满足约束条件,x2=2这条分支将被剪去,然而,当x1=1、x2=2、x3=3时,P(x1,x2,x3)= 5x1+4x2- x3=5*1+4*2 - 3=10,满足约束条件,即<1, 2, 3>是不等式的解,显然,此例中P(X3)不真蕴涵P(X2),违反了多米诺性质,从而丢解了。

如果令x’3=4-x3,将原不等式变换为:x1+4x2+x’3≤10 1≤x i, x’3≤3 i=1, 2则该不等式满足多米诺性质,可以使用回溯法,对所得到的解x1、x2、x’3转换成原不等式的解x1、x2、x3即可。

6.2回溯算法的经典例题6.2.1装载问题【例6-2】有一批共n个集装箱要装上一艘载重量为c的轮船,其中集装箱i的重量为w i。

找出一种最优装载方案,将轮船尽可能装满,即在装载体积不受限制的情况下,将尽可能重的集装箱装上轮船。

问题分析假设集装箱数量n=5,轮船的载重量c=10,每个集装箱的重量w={7,2,6,5,4}即w1=7,w2=2,w3=6,w4=5,w5=4。

5个物品的装载可以表示为一个五元组X=(x1,x2,x3,x4,x5),每个x代表一个集装箱,其值表示装载情况,由于每个集装箱装载只有两种可能:装和不装,所以,x i (i=1,2,3,4,5,表示集装箱编号)只能从0和1中选择其一,其中,0表示不装,1表示装载。

能否装载当前的集装箱,要看船上已装箱子的重量加上当前箱子的重量是否超过轮船的载重量,这个判断构成了评估函数P。

用回溯法进行求解,可以生成一棵解空间树。

因为有5个集装箱可以选择装载,所以最多判断到第5个箱子时,一轮搜索结束,并能得到问题的部分解,因此,问题的解空间树高为5,如图6-4所示。

解空间树的每一层代表一个集装箱,它有两个分支,左分支代表装载:x i =1,右分支代表不装载:x i =0。

执行的过程为:(1)选择第一个集装箱x1=1,判断是否超过船的载重:w1×x1=7×1=7<10,可装载。

(2)选择第二个集装箱x2=1,判断是否超过船的载重:w1×x1+ w2×x2=7+2×1=9<10,可装载。

(3)选择第三个集装箱x3=1,判断是否超过船的载重:w1×x1+ w2×x2+ w3×x3=9+6×1=15>10,不可装载。

观察图6-4,当不选择第三个集装箱时,第三层最左端下方结点以下的分支被裁掉(图6-4中虚线所示,即不再往下尝试),应当沿此结点的弧线向上回溯到第二层下面的结点,并沿其右分支继续选择,令x3 =0,有w1×x1+ w2×x2+ w3×x3=9+6×0=9<10。

相关文档
最新文档