“它是回溯法在命题约束上的具体化。撤销必须覆盖该决策层之后的所有传播赋值,却不能删除更早层的事实。变量选择与先试极性可以极大改变树大小,但只要两个分支最终都能被探索,它们不改变判定结果。”
形式陈述
回溯法把候选解空间组织成一棵搜索树:根是空部分解,每个节点是一个部分解,扩展操作枚举下一个决策的所有取值以生成孩子,叶子对应完整候选解。算法按深度优先搜索的次序遍历这棵隐式树,并配备可行性谓词:一旦谓词证明当前部分解不可能延伸为任何完整解,就剪掉整棵子树并回退,撤销最近的选择。
先明确搜索目标。若要枚举全部可行解,正确性要求每个输出都满足约束,且每个可行解至少对应一条未被剪断的根叶路径;此时可行性剪枝必须证明所有后代都不可行。若只需判断存在性或找一个解,分支与约简只须保证有解时至少保留一个见证;找到它即可停止。求最优解时,则要保留至少一个能达到最优值的候选,允许用有效目标界排除不可能改进的子树。
假定隐式搜索树有限且每次扩展、检查、撤销与结果输出均终止,遍历便会结束。总运行时间是各访问节点的扩展、检查与撤销成本之和,再加全部输出的写出成本;枚举时每个叶子可能写出一个很长的解,不能只计一次叶访问。访问节点数最坏仍可能是指数级。递归栈深度由搜索深度决定,此外还需计算部分解与辅助状态的存储;若保留全部解,还须计入输出存储。
直觉
回溯一边构造部分解,一边用约束判断它还能否完成:砍掉一个深度为
例子与边界
N 皇后问题逐行放置皇后,扩展时只生成与已放皇后不同列、不同两条对角线的位置。以
枚举全部解时,剪枝必须是不可行性的证明:把“启发式评分低”当作剪枝条件会砍掉真解、破坏完备性;若接受这种启发式截断,就失去了枚举全部可行解的保证。
原地修改共享状态时必须在返回前完全撤销(包括所有辅助标记),否则兄弟分支相互污染,产生难以复现的错误。
模式匹配的回溯字节码提供一种固定候选顺序的应用:失败标签转下一模式,成功标签共享后续检查。它在行入口清空临时绑定,or两臂成功时覆盖相同名字集合;guard失败进入下一源行,不能重新尝试已经提交的or替代。这套有限无环IR的状态约束须单独证明,不能从“用了回溯”四个字自动得到。
回溯与动态规划的适用面不同:回溯遍历彼此不同的部分解,动态规划靠重叠子问题的缓存获利;记忆化的收益取决于重复子问题的数量及重新求解它们的成本。
推论与应用
回溯是组合生成(排列、子集、划分的枚举)与约束满足求解的骨架:图着色、数独、拼图与调度都可写成逐变量赋值加剪枝。现代 SAT 求解器的祖先 DPLL 就是命题赋值上的回溯加单元传播。优化问题还允许另一类剪枝证书:整数规划分支定界用松弛界证明整棵子树不可能改善当前可行解,即使该子树仍有可行点也可以停止探索;这时目标是证明一个最优值,不是枚举全部解。与约束传播、对称性消除结合后,回溯在许多 NP 难问题的实际实例上远快于最坏界,但这仍不是多项式最坏保证。
若把搜索深度限制在参数
参考资料
- Jeff Erickson, Algorithms, 2019,Chapter 2 “Backtracking”:作者教材。隐式递归搜索、状态恢复与 N 皇后。