算法思想(四)回溯法 Backtracking Method
回溯法(探索与回溯法,Backtracking Method)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
基本做法就是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法 —— 适用于解一些组合数相当大的问题。
用爬山来比喻回溯,好比从山脚下找一条爬上山顶的路,起初有好几条道可走,当选择一条道走到某处时,又有几条岔道可供选择,只能选择其中一条道往前走,若能这样子顺利爬上山顶则罢了,否则走到一条绝路上时,只好返回到最近的一个路口,重新选择另一条没走过的道往前走。如果该路口的所有路都走不通,只得从该路口继续回返。照此规则走下去,要么找到一条到达山顶的路,要么最终试过所有可能的道,无法到达山顶。
回溯是一种穷举,但与brute force有一些区别,回溯带了两点脑子的,并不多,brute force一点也没带。
第一点脑子是回溯知道回头;相反如果是brute force,发现走不通立刻跳下山摔死,换第二条命从头换一条路走。
第二点脑子是回溯知道剪枝;如果有一条岔路上放了一坨屎,那这条路我们不走,就可以少走很多不必要走的路。还有一些爱混淆的概念:递归,回溯,DFS。
- 回溯是一种找路方法,搜索的时候走不通就回头换路接着走,直到走通了或者发现此山根本不通。
- DFS是一种开路策略,就是一条道先走到头,再往回走一步换一条路走到头,这也是回溯用到的策略。在树和图上回溯时人们叫它DFS。
- 递归是一种行为,回溯和递归如出一辙,都是一言不合就回到来时的路,所以一般回溯用递归实现;当然也可以不用,用栈。
回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。
- 算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。
- 如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;
- 否则,进入该子树,继续按深度优先策略搜索。
基本思想
- 针对所给问题,定义问题的解空间。
- 确定易于搜索的解空间结构。
- 以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。
方法
- 递归回溯:回溯法对解空间作深度优先搜索,因此,在一般情况下,用递归方法实现回溯法。
- 迭代回溯:采用树的非递归深度优先遍历算法,可将回溯法表示为一个非递归迭代过程。
效率分析
回溯算法的效率在很大程度上依赖于以下因素:
- 产生x[k]的时间;
- 满足显约束的x[k]值的个数;
- 计算约束函数constraint的时间;
- 计算上界函数bound的时间;
- 满足约束函数和上界函数约束的所有x[k]的个数。
好的约束函数能显著地减少所生成的结点数。但这样的约束函数往往计算量较大。因此,在选择约束函数时通常存在生成结点数与约束函数计算量之间的折衷。