0%

回溯算法

深度优先搜索利用的是回溯算法思想。
回溯算法大部分情况下都是用来解决广义的搜索问题:从一组可能的解中,选出一个满足要求的解。

回溯算法非常适合用递归来实现,在实现的过程中,剪枝操作是提高回溯效率的一种技巧,利用剪枝,并不需要穷举搜索所有的情况,从未提高搜索效率。

回溯算法理解

对比贪心算法,在每次面对岔路口的时候,都做出看起来最优的选择,期望这一组选择是最终的最优解。但是贪心算法并不一定能得到最优解。

回溯的处理思想,类似枚举搜索。枚举所有的解,找到满足期望的解。为了有规律的枚举所有可能的解,避免遗漏和重复,把问题求解的过程分为多个阶段。每个阶段都有会面对一个岔路口,先随意选一条路走,当发现这条路走不通的时候(不符合期望的解),就退回到上一个岔路口,另选一种走法继续走。

回溯算法应用

八皇后问题1

有一个8X8的棋盘,希望往里放8个棋子(皇后),每个棋子所在的行、列、对角线都不能有另一个棋子。

把这个问题分成8个阶段,依次将8个棋子放到第一行、第二行、第三行…第八行。在放置的过程中,不停地检查当前放法,是否满足要求。如果满足,则跳到下一行继续放置棋子;如果不满足,那就再换一种放法,继续尝试。2

0-1背包
动态规划
回溯算法
一个背包,背包总的承载重量是Wkg。现在有n个物品,每个物品的重量不等,并且不可分割。期望选择几件物品,装载到背包中,在不超过背包所能装载重量的前提下,让背包中物品的总重量最大。

对于每个物品来说,都有两种选择,装进背包或者不装进背包。对于n各物品来说,总的装法就有2n种,去掉总重量超过Wkg的,从剩下的装法中选择总重量最接近Wkg的。
把物品依次排列,整个问题就分解成了n个阶段,每个阶段对应一个物品怎么选择,先对第一个物品进行处理,选择装进去或者不装进去,然后再递归地处理剩下的物品。

变体:每个物品重量不同,价值不同,在不超过背包重量的情况下,让背包中的总价值最大。

正则表达式
背景假设,正则表达式中只包含“”和“?”这两种通配符,其中“”匹配任意多个(>=0个)任意字符,“?”匹配另个或者一个任意字符。

依次考察正则表达式中的每个字符,当是非通配符时,就直接跟文本的字符进行匹配,如果相同,则继续往下处理;如果不同,则回溯。
如果遇到特殊字符的时候,也就是岔路口,“*”,先随意的选择一种匹配方案,然后继续考察剩下的字符,如果中途发现无法继续匹配下去,就回溯到岔路口,重新选择一种匹配方案,然后再继续匹配剩下的字符。

参考