第5章 搜索法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
排列树
• 当所给的问题是从n个元素的排列中找出满足 某种性质的一个排列时,相应的解空间树称 为排列树。 • 此类问题解的形式为n元组(x1,x2,…,xn), 分量xi(i=1,2,…,n)表示第i个位置的元素是xi。 n个元素组成的集合为S={1,2,…,n},xi∈S{x1,x2,…,xi-1},i=1,2,…,n。 • n=3时的排列树如图5-17所示:
回溯法
• 回溯法是在仅给出初始结点、目标结点及 产生子结点的条件(一般由问题题意隐含 给出)的情况下,构造一个图(隐式图), 然后按照深度优先搜索的思想,在有关条 件的约束下扩展到目标结点,从而找出问 题的解。 • 通俗地讲:回溯法是一种“能进则进,进 不了则换,换不了则退”的基本搜索方法
回溯法的基本思想
迭代回溯(非递归算法)
采用树的非递归深度优先遍历算法,可将回溯法表示 为一个非递归迭代过程。 void NBacktrack () { int t=1; while (t>0) { if (s(n,t)<=e(n,t)) for (int i=s(n,t);i<=e(n,t);i++) { x[t]=d(i); if (constraint(t)&&bound(t)) { if (t>n) output(x); else t++;} //进入更深层搜索 } else t--; //回溯到上一层的活结点 } }
• 从根开始,以深度优先搜索的方式进行搜索。 • 根结点是活结点并且是当前的扩展结点。在搜索的 过程中,当前的扩展结点向纵深方向移向一个新结 点,判断该新结点是否满足隐约束。 • 如果满足,则新结点成为活结点,并且成为当前的 扩展结点,继续深一层的搜索; • 如果不满足,则换该新结点的兄弟结点(扩展结点 的其它分支)继续搜索; • 如果新结点没有兄弟结点,或其兄弟结点已全部搜 索完毕,则扩展结点成为死结点,搜索回溯到其父 结点处继续进行。 • 搜索过程直到找到问题的解或根结点变成死结点为 止。
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皇后问题为例)
• 示列
– 给定一个有向带权图G=(V,E),权非负,如图5-1 所示。找出顶点1→5的最短路径及其长度。
1 2 3 1 4 2 1 5 1 4
3
1
图5-1 有向带权图
• 问题分析
– 该问题所有可能的路径只有 三条,分别是:
• 1→2→4→5 • 1→3→4→5 • 1→4→5
– 采用穷举搜索的方法逐一检 查这三条路径的长度。 – 最短路径为1→2→4→5,其 长度为3。
递归回溯Biblioteka Baidu
回溯法对解空间作深度优先搜索,因此,在一般情况下用递归方法实 现回溯法。
void backtrack (int t) { if (t>n) output(x); //已到叶子结点,输出结果 else for (int i=s(n,t);i<=e(n,t);i++) //检查扩展结点的每个分支 { x[t]=d(i); if (constraint(t)&&bound(t)) backtrack(t+1);} //如果满足,进入t+1层继续搜索 } s(n,t) ,e(n,t) :表示当前扩展结点处未搜索过的子树的起始 编号和终止编号。 d(i):表示在当前扩展结点处x[t]的第i个可选值。 constraint(t):约束函数,bound(t):限界函数
A
x1=1 x1=2 x1=3
x1=4
B
Q
x2=3 x2=4
F
x2=4 x2=1
J
x2=1
N
x2=2
Q Q Q
C
x3=2
D E
G
x3=1
K
x3=4
O
x3=3
Q P
H
x4=3
L
x4=2
I
M
4皇后问题的搜索树
n后问题
•解向量:(x1, x2, … , xn) •显约束:xi=1,2, … ,n •隐约束: 1)不同列:xixj 2)不处于同一正、反对角线:|i-j||xi-xj|
回溯法的基本思想
例如:n=3的0——1 背包问题的回溯法搜索过程。 W=[16,15,15] p=[45,25,25] C=30
回溯法的基本思想
例如2:旅行售货员问题。某售货员要到若干城市去 推销商品,已知各城市之间的路程(旅费),他要 选定一条从驻地出发,经过每个城市一遍,最后回 到驻地的路线,使总的路程(总旅费)最小。
n=3时的0-1背包问题用完全二叉树表示的解空间
生成问题状态的基本方法
• 扩展结点:一个正在产生儿子的结点称为扩展结点 • 活结点:一个自身已生成但其儿子还没有全部生成的节点称 做活结点 • 死结点:一个所有儿子已经产生的结点称做死结点 • 深度优先的问题状态生成法:如果对一个扩展结点R,一旦 产生了它的一个儿子C,就把C当做新的扩展结点。在完成对 子树C(以C为根的子树)的穷尽搜索之后,将R重新变成扩 展结点,继续生成R的下一个儿子(如果存在) • 深度优先的问题状态生成法:在一个扩展结点变成死结点之 前,它一直是扩展结点 • 回溯法:为了避免生成那些不可能产生最佳解的问题状态, 要不断地利用限界函数(bounding function)来处死那些实 际上不可能产生所需解的活结点,以减少问题的计算量。 具有限界函数的深度优先生成算法称为回溯法
回溯法的解题步骤
(1)针对所给问题,定义问题的解空间; (2)确定易于搜索的解空间结构; (3)以深度优先方式搜索解空间,并在搜 索过程中用剪枝函数避免无效搜索。
常用剪枝函数: 用约束函数在扩展结点处剪去不满足约束的子树; 用限界函数剪去得不到最优解的子树。
回溯法的基本思想
确定了解空间的组织结构后,回溯法就从开始结点(根) 出发,以深度优先的方式搜索整个解空间。这个开始结点就成为 一个活结点,同时也成为当前的扩展结点。在当前的扩展结点处, 搜索向纵深方向移至一个新结点。这个新结点就成为了一个新的 活结点,并成为当前扩展结点。如果在当前的扩展结点处不能再 向纵深方向移动,则当前的扩展结点就成为死结点。此时,应往 回移动(回溯)至最近的一个活结点处,并使这个活结点成为当 前的扩展结点。回溯法即以这种工作方式递归地在解空间中搜索, 直至找到所要求的解或解空间中已无活结点时为止。 用回溯法解题的一个显著特征是在搜索过程中动态产生问题的 解空间。在任何时刻,算法只保存从根结点到当前扩展结点的 路径。如果解空间树中从根结点到叶结点的最长路径的长度为 h(n),则回溯法所需的计算空间通常为O(h(n))。而显式地存储 整个解空间则需要O(2h(n))或O(h(n)!)内存空间。
问题的解空间
• 问题的解向量:回溯法希望一个问题的解能够表示成一个n 元式(x1,x2,…,xn)的形式。 • 显约束:对分量xi的取值限定(即:x的取值)。 • 隐约束:为满足问题的解而对不同分量之间施加的约束。 • 解空间:对于问题的一个实例,解向量满足显式约束条件 的所有多元组,构成了该实例的一个解空间。 注意:同一个问题可以有多种表示,有些表示方法更简单, 所需表示的状态空间更小(存储量少,搜索方法简单)。
子集树与排列树
遍历子集树需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!)计算时间
子集树
• 当所给的问题是从n个元素组成的集合S中 找出满足某种性质的一个子集时,相应的 解空间树称为子集树。 • 此类问题解的形式为n元组(x1,x2,…,xn), 分量xi(i=1,2,…,n)表示第i个元素是否在要找 的子集中。 • xi的取值为0或1,xi=0表示第i个元素不在要 找的子集中;xi=1表示第i个元素在要找的 子集中。
5.2深度优先搜索
• 思想(给定图G=(V,E))
– 初始时,所有顶点均未被访问过,任选一个顶点v作为源 点。该方法先访问源点v,并将其标记为已访问过;然后 从v出发,选择v的一个邻接点(子结点)w,如果w已访 问过,则选择v的另外一个邻接点;如果w未被访问过,则 标记w为已访问过,并以w为新的出发点,继续进行深度 优先搜索;如果w及其子结点均已搜索完毕,则返回到v, 再选择它的另外一个未曾访问过的邻接点继续搜索,直到 图中所有和源点有路径相通的顶点均已访问过为止;若此 时图G中仍然存在未被访问过的顶点,则另选一个尚未访 问过的顶点作为新的源点重复上述过程,直到图中所有顶 点均已访问过为止。
示例1:0-1 背包问题
• 问题描述
– 给定n种物品和一背包。物品i的重量是wi,其价值为vi, 背包的容量为W。一个物品要么全部装入背包,要么 全部不装入背包,不允许部分装入。装入背包的物品 的总重量不超过背包的容量。问应如何选择装入背包 的物品,使得装入背包中的物品总价值最大?
• 定义问题的解空间
第5章 搜索法
第五章 搜索法
• 教学目标
– 掌握回溯法的算法框架 – 理解回溯法及分支限界法的基本思想 – 掌握回溯法及分支限界法的异同 – 掌握子集树、排列树及满m叉树的算法设计模式 – 通过实例学习,掌握回溯法及分支限界法解决问 题的方法步骤
5.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]); } }
子集树举例
private static boolean place (int k) { for (int j=1;j<k;j++) if ((Math.abs(k-j)==Math.abs(x[j]-x[k]))||(x[j]==x[k])) return false; return true; } private static void backtrack (int t) { if (t>n) sum++; else for (int i=1;i<=n;i++) { x[t]=i; if (place(t)) backtrack(t+1); }
示例:n后问题
问题描述: 在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际 象棋的规则,皇后可以攻击与之处在同一行或同一列或同 一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n 个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。
1 2 3 4 5 Q Q Q Q Q Q
6 7 8
回溯法
回溯法有“通用的解题法”之称。用 它可以系统地搜索一个问题的所有解或任 一解。
回溯法
• 有许多问题,当需要找出它的解集或者要求回答什 么解是满足某些约束条件的最佳解时,往往要使用 回溯法。 • 回溯法的基本做法是搜索,或是一种组织得井井有 条的,能避免不必要搜索的穷举式搜索法。这种方 法适用于解一些组合数相当大的问题。 • 回溯法在问题的解空间树中,按深度优先策略,从 根结点出发搜索解空间树。算法搜索至解空间树的 任意一点时,先判断该结点是否包含问题的解。如 果肯定不包含,则跳过对该结点为根的子树的搜索, 逐层向其祖先结点回溯;否则,进入该子树,继续 按深度优先策略搜索。
思考:进一步改进?
定义问题的解空间 解的形式:(x1, x2, … , xn) xi的取值范围:xi∈S-{x1, x2, … , xi-1} 思考:该解空间比改进前少了多少可能的 解? 组织解空间 排列树,树的深度为n 搜索解空间 约束条件:不处于同一正、反对角线:|ij||xi-xj| 限界条件:(×)