回溯法的根本思想
对于一个问题求解过程中不断地去依据现在的状态,遍历下一个可能状态的集合。
这里要保存的东西有:
- 所有的历史路径
- 每一个路径可能去的下一路径的集合。
这种记忆方式的产生原因:是考虑所有的状态与状态之间有时间的先后顺序。
整个递归树的遍历点的路径画出来之后,看上去就很麻烦。
所以复杂性(不是复杂度)来自于这种路径而不是树本身。因为问题的解空间确定了,在解空间中寻找一个或多个解。那么算法的复杂性来源于如何在解中选择。这个时候思考问题的时候不能仅仅把解空间看作数学定义的那样,是一个线性表。因为问题本身是树型的,把树型的解的形状压缩为线性的形状是要付出代价的。
而这种代价的支付方式可能是预处理,如果这种预处理能把例如复杂度是 n3 压缩为两个 n2 当然是最好的。当然也有可能存在别的压缩方式,或者是复杂的变换。
注意:这里提到过解的形状。解的形状往往是我们所忽略的,在大部分情况中我们会忽略,因为形状本身不会影响。但是有的时候形状本身就会产生影响。对于解的形状想要了解更多,推荐阅读 SICP 这本魔法书。
递归下降
在使用回溯法的时候,一种简单的实现方法就是使用递归遍历。但是在很多时候递归的性能不是很好。所以有人想出来了递归下降。
递归下降是一种十分直接暴力的方法,其根本思想就是取消每次当前状态和下一状态的来回移动。其实在算法之中就提到过这个递归算法的学名:bound function
。这是其