回溯法&分支限界

一、回溯法

1. 算法简介

回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
没有学过算法的时候肯定首选蛮力法,即遍历每一种可能的结果。其实,蛮力法与回溯法都被称为“万能解题法”,本质都是搜索技术。区别是,蛮力法遍历所有可能的结果,最终再统一进行判定是否合法,然后寻找最优解,而回溯法相比于蛮力法最大的优点就是剪枝,即及时判断不合法的地方,并将以不合法节点为根节点的子树全部剪掉。
若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。 而若使用回溯法求任一个解时,只要搜索到问题的一
个解就可以结束。

2. 基本概念与使用条件

(1)基本概念:

1)两个常用的剪枝函数:

(1) 约束函数: 在扩展节点处减去不满足约束的子树
(2) 限界函数: 减去得不到最优解子树

2)扩展结点:一个正在产生儿子的结点称为扩展结点

3)活结点:一个自身已生成但其儿子还没有全部生成的节点称做活结点

4)死结点:一个所有儿子已经产生的结点称做死结点

5)深度优先的问题状态生成法:如果对一个扩展结点R,一旦产生了它的一个儿子C,就把C当做新的扩展结点。在完成对子树C(以C为根的子树)的穷尽搜索之后,将R重新变成扩展结点,继续生成R的下一个儿子(如果存在)

6)广度(宽度)优先的问题状态生成法:在一个扩展结点变成死结点之前,它一直是扩展结点

7)回溯法:为了避免生成那些不可能产生最佳解的问题状态,要不断地利用限界函数(bounding function)来减掉那些实际上不可能产生所需解的活结点,以减少问题的计算量。具有限界函数的深度优先生成法称为回溯法

8)子集树:所给的问题是从n个元素的集合S中找出满足某种性质的子集时,相应的解空间成为子集树。遍历子集树需O(2^n)计算时间

9)排列树:所给的问题是确定n个元素满足某种性质的排列时,相应的解空间就是排列树。遍历排列树需要O(n!)计算时间

(2)适用条件:

回溯算法的使用需要满足 —— 多米诺性质,即:
回溯法&分支限界_第1张图片
现在可能对多米诺性质不是很理解,下面来看一个反例:
回溯法&分支限界_第2张图片
仔细思考一下就能理解为什么需要满足多米诺性质了:因为我们只要发现不合法的节点(超载等),就直接将以该节点为根节点的子树全部剪掉。而为什么能全部剪掉呢?因为k一旦不满足,则k+1及之后就永远不满足了(即多米诺性质的逆否命题)。

3. 示例:

(1)示例1(最大装载问题)

回溯法&分支限界_第3张图片

伪代码:

算法 Loading(W,c1),
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 最优解

算法Backtrack(i)
while i > 1 and x[i] = 0 do
  i <-- i - 1;
if x[i] = 1
then x[i] <-- 0;
  B <-- B + w;
  i <-- i + 1;

下面是此问题的一个例子:
回溯法&分支限界_第4张图片

(2)示例2(图着色问题):

回溯法&分支限界_第5张图片
回溯法&分支限界_第6张图片

(3)示例3(0-1背包问题):

回溯法&分支限界_第7张图片
因为每一种物品要么选取要么不选取,即0或1,因此解空间一共有8种:
回溯法&分支限界_第8张图片
我们按深度优先搜索进行遍历,给问题满足多米诺性质,比如,在某节点装载情况已经超过了载重量,那么直接将之后的所有节点剪枝即可。因为此时已超重,再进行装载必然会超重。此外,当我们搜索完某一枝时,再搜索其他的枝时,只要当前节点以及之前的装载情况的价值加上剩余物品全部装载的价值低于该优化解,则进行剪枝。详细步骤如下:
回溯法&分支限界_第9张图片
回溯法&分支限界_第10张图片
回溯法&分支限界_第11张图片
回溯法&分支限界_第12张图片
回溯法&分支限界_第13张图片
回溯法&分支限界_第14张图片

二、分支限界

1. 算法简介:

回溯法&分支限界_第15张图片

你可能感兴趣的:(算法,算法)