本文共 1198 字,大约阅读时间需要 3 分钟。
回溯法有“通用解题法”之称。用它可以系统地索索一个问题的所有解和任一解。它是一个既带有系统性又带有跳跃性的搜索算法。它在问题的解空间树中,按深度优先遍历的策略,从根结点出发搜索解空间树。算法搜索到解空间树的任一结点时,先判断该结点是否包含包含问题的解。如果不包含则跳过对以该结点为根的子树的搜索,逐层向其父结点回溯。否则进入该子树,继续按深度优先策略搜索。只求一个解时只要第一搜索到叶子结点,从叶子结点到根结点的路径就是一个可行解;求解全部解时,需要遍历完全空间。
通常来说,越是限制越低的算法,其算法越依赖于计算机本身的运行速度。越是通用的方法,越是采用不取巧的方式。一般来说也是比较无奈并很难改进效率的。
通过分析上面算法的定义可以得到回溯法的步骤:
1.针对问题,定义问题的解空间
2.确定易于搜索的解空间结构
3.以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。
只有3当中的剪枝函数是定义中没有提到的。剪枝函数时用来判定搜索到的当前结点是否是有效的,无效的灵敏度越高,算法的运行速度越快。
递归式回溯函数定义形式
void backTrack(int t){ if(t>n) { output(x); }else{ for(int i=f(n,t) ; i<=g(n,t); i++){ x[t]=h(i); if(constraint(t)&&bound(t)){ backTrack(t+1); } } } }形式参数t表示递归深度,即当前扩展结点在解空间树中的深度。n用来控制递归深度,当t > n时表示算法已搜索到叶结点。output(x)记录或者输出得到的可行解x。f(n,t) 和 g(n,t) 表示在当前扩展结点处未搜索子树 的起始编号和终止编号。h(i)表示在当前扩展结点处x[t]的第i个可选值。constraint(t) 和 bound(t) 表示在当前扩展结点处的约束函数和限界函数。constraint(t) 为true时表示当前结点处的取值满足约束条件,否则剪枝处理。bound(t) 为true时表示在当前结点处取值没有越界,需要backTrack(t+1)进一步搜索。
回溯算法的效率分析
回溯算法的效率很大程度上依赖于以下因素:
1.产生x[k]的时间
2.满足显约束条件的x[k]值的个数
3.计算约束函数constraint(k)的时间
4.计算上界函数 bound(k)的时间
5.满足约束函数和上界约束函数的所有x[k]的个数
设计算法的时候需要重点关注解空间树的排列结构和估算可行解的个数。
一般情况下用到二叉树,森林,B-树,堆的解结构的可以考虑回溯法。
转载地址:http://zgpdi.baihongyu.com/