回溯法——回溯法的算法思想

 参考了一篇写的较好的博客

[回溯算法] 五大常用算法之回溯法_GoRustNeverStop的博客-CSDN博客_回溯算法 


简单来说,回溯法是一个在所有可能性中寻找最优解的问题,但与遍历所有路径的全遍历不同的是:回溯法可能在中间的某一步产生了分支,我们在遍历路径的时候,可以选择从原来选择后的路径倒退回那个分叉路口,选择其他的分支。通过对各个分支的探索遍历完整个解空间,而不是每次都从起点开始遍历。比如经过了ABDH,我们也可以选择回溯去走ABDI,走完了D的两个分支我们还可以回到B分叉选择ABEJ。

就像玩多结局的文字游戏一样,我们在每个分支选项存档,如果想要体验其他分支不必重新开档从头开始,而是回到之前保存存档的那个分支去走其他选项。


递归回溯应该是最好理解的,它实际上就是对解空间的这颗树的深度优先遍历。f(n,t)中的f代表first,即分叉中第一个未经历的子树分支的起始编号,g(n,t)代表分叉中未经历过的子树分支的结束编号。我们对每一个分支都应当遍历,当到达叶子结点则输出。 而递归的调用应当是每层一个递归,若符合约束条件则进入下一层。Backtrack(t)中的t代表的就是树的深度(层次)。


 迭代回溯是非递归的,不过仔细观察不难发现有一段代码和递归回溯是一模一样的。同样t仍然代表树深度,f(n,t)代表分叉中第一个未经历的子树分支的起始编号,g(n,t)代表分叉中未经历过的子树分支的结束编号。其实不难发现,迭代和递归的算法本质是一样的,只不过递归中算法嵌套,有分支就会进入下一层t++,内层递归结束回归外层t--。在迭代中则用while把这个过程表达了出来,迭代回溯同样也是深度优先算法。


 

 子集树就是从有限的解空间里去寻找答案的集合,就是用我们平时的调用回溯法找出一个或多个解。解向量所需元素m往往比给出的元素数量n要小。

排序树就是n个元素需要按照一定的要求(性质)进行某种排序,其结果往往含有所有元素。它的树深度往往是n。

观察代码可以发现搜索排序树的回溯法就多了个Swap函数来排序结果,比如123是以1为分支的一个结果,遍历了123,132后,下一个有规律的结果就是将第一位的1和后面两位互换,也就是213与231,同理将第一位的1和3互换就是321和312。而且排序树每一次的分支选择都是建立在上一次经过其他分支的基础上的,所以这一层每一次互换都不会考虑上一层分支,所以i=t,比如1?是确定了第一个分支为1,接下来i=t=2,就考虑是123或者132。总而言之排序树是按照数的全排序的顺序来建立树的。


不难发现,其实回溯法的核心都是一样的算法,其本质都是对解空间构成树的深度优先遍历,子集树和排序树则属于不同的构建树的方法,但是回溯法的核心都是深度优先遍历。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值