回溯法概述—BackTracking

原创 2015年11月18日 15:55:52

1.问题的解空间

  复杂问题常常有很多的可能解,这些可能解构成了问题的解空间。解空间也就是进行穷举的搜索空间,所以,解空间中应该包括所有的可能解。确定正确的解空间很重要,如果没有确定正确的解空间就开始搜索,可能会增加很多重复解,或者根本就搜索不到正确的解。
对于任何一个问题,可能解的表示方式和它相应的解释隐含了解空间及其大小。
  例如,对于有n个物品的0/1背包问题,其可能解的表示方式可以有以下两种:
(1)可能解由一个不等长向量组成,当物品i(1≤i≤n)装入背包时,解向量中包含分量i,否则,解向量中不包含分量i,当n=3时,其解空间是:
{ ( ), (1), (2), (3), (1, 2), (1, 3), (2, 3), (1, 2, 3)}
(2)可能解由一个等长向量{x1, x2, …, xn}组成,其中xi=1(1≤i≤n)表示物品i装入背包,xi=0表示物品i没有装入背包,当n=3时,其解空间是:
{(0, 0, 0), (0, 0, 1), (0, 1, 0), (1, 0, 0), (0, 1, 1), (1, 0, 1), (1, 1, 0), (1, 1, 1) }
  为了用回溯法求解一个具有n个输入的问题,一般情况下,将其可能解表示为满足某个约束条件的 等长向量 X=(x1, x2, …, xn),其中分量xi (1≤i≤n)的取值范围是某个有限集合Si={ai1, ai2, …, airi},所有可能的解向量构成了问题的解空间
  问题的解空间一般用解空间树(Solution Space Trees,也称状态空间树)的方式组织,树的根结点位于第1层,表示搜索的初始状态,第2层的结点表示对解向量的第一个分量做出选择后到达的状态,第1层到第2层的边上标出对第一个分量选择的结果,依此类推,从树的根结点到叶子结点的路径就构成了解空间的一个可能解
  对于n=3的0/1背包问题,其解空间树如图1所示,树中的8个叶子结点分别代表该问题的8个可能解。

这里写图片描述

  对于n=4的TSP问题,其解空间树如图2所示,树中的24个叶子结点分别代表该问题的24个可能解,例如结点5代表一个可能解,路径为1→2→3→4→1,长度为各边代价之和。
这里写图片描述

这里写图片描述

2.解空间树的动态搜索

  回溯法从根结点出发,按照深度优先策略遍历解空间树,搜索满足约束条件的解。在搜索至树中任一结点时,先判断该结点对应的部分解是否满足约束条件,或者是否超出目标函数的界,也就是判断该结点是否包含问题的(最优)解,如果肯定不包含,则跳过对以该结点为根的子树的搜索,即所谓剪枝(Pruning);否则,进入以该结点为根的子树,继续按照深度优先策略搜索。
根据约束函数剪枝:
  例如,对于n=3的0/1背包问题,三个物品的重量为{20, 15, 10},价值为{20, 30, 25},背包容量为25,从图2所示的解空间树的根结点开始搜索,搜索过程如下:

这里写图片描述

根据目标函数剪枝:
  再如,对于n=4的TSP问题,其代价矩阵如图4所示,

这里写图片描述

这里写图片描述

  回溯法的搜索过程涉及的结点(称为搜索空间)只是整个解空间树的一部分,在搜索过程中,通常采用两种策略避免无效搜索:
(1)用约束条件剪去得不到可行解的子树;
(2)用目标函数剪去得不到最优解的子树。
  这两类函数统称为剪枝函数(Pruning Function)。
  需要注意的是,问题的解空间树是虚拟的,并不需要在算法运行时构造一棵真正的树结构,只需要存储从根结点到当前结点的路径。

  由于问题的解向量X=(x1, x2, …, xn)中的每个分量xi(1≤i≤n)都属于一个有限集合Si={ai1, ai2, …, airi},因此,回溯法可以按某种顺序(例如字典序)依次考察笛卡儿积S1×S2×…×Sn中的元素。
  初始时,令解向量X为空,然后,从根结点出发,选择S1的第一个元素作为解向量X的第一个分量,即x1= a11,如果X=(x1)是问题的部分解,则继续扩展解向量X,选择S2的第一个元素作为解向量X的第2个分量,否则,选择S1的下一个元素作为解向量X的第一个分量,即x1= a12。依此类推,一般情况下,如果X=(x1, x2, …, xi)是问题的部分解,则选择Si+1的第一个元素作为解向量X的第i+1个分量时,有下面三种情况:
(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);
这里写图片描述

回溯法的一般框架:

//递归形式
主算法
1. X={ };
2. flag=false;
3. advance(1);
4. if (flag) 输出解X;
else输出“无解”;

advance(int k)
1. 对每一个x∈Sk循环执行下列操作
  1.1 xk=x;
  1.2 将xk加入X;
  1.3 if (X是最终解) flag=true; return;
  1.4 else if (X是部分解) advance(k+1);
//迭代形式
1.X={ };
2.flag=false;
3.k=1;
4while (k>=1)
      4.1 当(Sk没有被穷举)循环执行下列操作
            4.1.1 xk=Sk中的下一个元素;
            4.1.2 将xk加入X;
            4.1.3 if (X为最终解) flag=true; 转步骤5;
            4.1.4 else if (X为部分解) k=k+1; 转步骤4;
      4.2 重置Sk,使得下一个元素排在第1位;
      4.3 k=k-1;    //回溯
5if flag 输出解X;
      else 输出“无解”;

3.回溯法的求解过程

  一般情况下,在问题的解向量X=(x1, x2, …, xn)中,分量xi (1≤i≤n)的取值范围为某个有限集合Si={ai1, ai2, …, airi},因此,问题的解空间由笛卡儿积A=S1×S2×…×Sn构成,并且第1层的根结点有|S1|棵子树,则第2层共有|S1|个结点,第2层的每个结点有|S2|棵子树,则第3层共有|S1|×|S2|个结点,依此类推,第n+1层共有|S1|×|S2|×…×|Sn|个结点,他们都是叶子结点,代表问题的所有可能解。
  在用回溯法求解问题时,常常遇到两种典型的解空间树:
(1)子集树(Subset Trees):当所给问题是从n个元素的集合中找出满足某种性质的子集时,相应的解空间树称为子集树。在子集树中,|S1|=|S2|=…=|Sn|=c,即每个结点有相同数目的子树,通常情况下c=2,所以,子集树中共有2n个叶子结点,因此,遍历子集树需要Ω(2n)时间。(如:0/1背包问题)
(2)排列树(Permutation Trees):当所给问题是确定n个元素满足某种性质的排列时,相应的解空间树称为排列树。在排列树中,通常情况下,|S1|=n,|S2|=n-1,…,|Sn|=1,所以,排列树中共有n!个叶子结点,因此,遍历排列树需要Ω(n!)时间。(如:TSP问题)
  对于n=1的0/1背包问题,其解空间树如图2所示,树中的8个叶子结点分别代表该问题的8个可能解。
  对于n=2的TSP问题,其解空间树如图3所示,树中的24个叶子结点分别代表该问题的24个可能解,例如结点5代表一个可能解,路径为1→2→3→4→1,长度为各边代价之和。

版权声明:本文为博主原创文章,未经博主允许不得转载。如果转载一定要通知博主哦~~

相关文章推荐

(Leetcode)backtracking回溯法 题目汇总

回溯法 Backtracking Backtracking比较形象来说可以用走迷宫做例子,大多人类一般就是使用回溯法,当走到一条死路,就往回退到前一个岔路,尝试另外一条,直到走出。 简介中文称做「...

用回溯法(backtracking)解决平衡集合问题(一道微软公司面试题)

(原题出自微软公司面试题)问题如下: 有两个序列a,b,大小都为n,序列元素的值任意整数,无序; 要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。 例如:...

迷宫问题(MazePath)的求解——利用回溯法(backtracking)

迷宫问题(MazePath)的求解——利用回溯法(backtracking) 1. 迷宫问题的提法 迷宫问题是典型的图的搜索问题。 假设一个迷宫,只有一个入口和一个出口。如果从迷宫的入口到达出口,...
  • cainv89
  • cainv89
  • 2016年05月25日 23:07
  • 5785

回溯法(Backtracking)

回溯法回溯法概念回溯算法有“通用的解题法”之称。用它可以系统地搜索一个问题的所在解或任一解。回溯法是一个即带有系统性又带有跳跃性的所搜算法。回溯法思想在包含问题的所有解的解空间树中,按照深度优先搜索的...

回溯(Backtracking)

以下是我个人对回溯的理解。 回溯,是尝试列举出所有解决问题的方法。 即按照问题所给的操作方法,进行模拟,当在寻找解的过程中,发现不符合题意的解,返回至上一步,如此重复,直到寻找到满足问题的解的过程...

回溯算法(BackTracking)--八皇后问题

0) 回溯算法: 回溯算法也算是遍历算法的一种,回溯算法是对Brute-Force算法的一种改进算法,一个典型的应用是走迷宫问题,当我们走一个迷宫时,如果无路可走了,那么我们就可以退一步,再在其他的路...

回溯算法(Backtracking)说明与实例

定义回溯算法(Backtracking)在很多场景中会使用,如N皇后,数迷,集合等,其是暴力求解的一种优化。参考https://en.wikipedia.org/wiki/Backtracking 中...

LeetCode 回溯算法 backtracking

1. Sudoku Solver rite a program to solve a Sudoku puzzle by filling the empty cells. Empty c...
  • sbitswc
  • sbitswc
  • 2014年03月07日 06:41
  • 1836

Letter Combinations of a Phone Number ---------backtracking 回溯算法的例子,

题目链接https://leetcode.com/problems/letter-combinations-of-a-phone-number/ 一开始没想到该怎么做,然后看了下标签,里面写着回溯,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:回溯法概述—BackTracking
举报原因:
原因补充:

(最多只允许输入30个字)