Chapter 4 Backtracking Search Algorithms

求解约束满足问题的算法技术主要有三种:回溯搜索、局部搜索和动态规划。本章主要研究回溯搜索算法。基于动态规划[15]的算法——有时在文献中称为变量消除、综合或推理算法——是第7章的主题。局部或随机搜索算法是第五章的主题。

约束满足问题的求解算法可以是完全的,也可以是不完全的。完整的,或系统的算法,如果存在一个解决方案就保证能找到,也可以用来表明一个CSP没有解决方案,或找到一个可证明的最优解决方案。回溯搜索算法和动态规划算法通常是完整算法的例子。不完全或非系统的算法,不能用来表明一个CSP没有一个解决方案或找到一个可证明的最优解决方案。然而,这种算法通常能够有效地找到一个存在的解,并且可以用来找到最优解的近似。局部或随机搜索算法是不完全算法的例子

在回溯搜索和动态编程这两类完全算法中,回溯搜索算法目前在实践中是最重要的。 动态编程方法的缺点是它们通常需要指数量的时间和空间,并且它们通过发现或使得可以容易地生成CSP的所有解决方案来执行不必要的工作。 但是,很少有人希望在实践中找到CSP的所有解决方案。 相反,回溯搜索算法一次只能处理一个解,因此只需要多项式的空间量。

自从40多年前[30,57]的回溯算法的第一个正式陈述以来,已经提出并评估了许多用于提高回溯搜索算法的效率的技术。 在本章中,我将研究一些最重要的技术,包括分支策略,约束传播,nogood记录,回跳,变量和值排序的启发式,随机化和重启策略,以及深度搜索的替代方法。这些技术并不总是正交的,有时将两种或两种以上的技术合并到一个算法中会产生乘法效果(例如将重启和nogood记录合并在一起),有时还会产生退化效果(例如增加约束传播而不是向后跳跃)。鉴于这些技术可以组合成一种算法的多种可能方法,我还对回溯算法进行了比较研究。这些技术的最佳组合产生了健壮的回溯算法,这些算法现在可以常规地解决具有实际重要性的大型硬实例。

4.1 Preliminaries

在本节中,我首先定义约束满足问题,然后简要回顾回溯搜索所需的背景知识。

每个约束C是一个关系——一组tuple——在一些变量集上的关系,由vars(C)表示。集合vars(C)的大小称为约束的浓度。一元约束是浓度1的约束,二元约束是浓度2的约束,非二元约束是浓度大于2的约束,全局约束是可以超越变量的任意子集的约束。约束可以通过指定约束中的元组必须满足的公式来内涵地指定,也可以通过显式地列出约束中的元组来扩展。CSP的解决方案是为每个变量分配一个值,使其满足所有约束。如果不存在解决方案,则CSP被认为是不一致的或不能满足的。

可满足性问题(SAT)是一个CSP,其中变量的域是布尔值,约束是布尔公式。我将假设约束是合取范式,因此被写成子句。字(A literal )是布尔变量或其否定,子句(A clause )是文字的析取。例如,公式¬x1∨x2∨x3是一个子句。只有一个字的子句叫做单位子句 a unit clause;没有文字的子句称为空子句 the empty clause。空子句是不可满足的。

对CSP解决方案的回溯搜索可以看作是对搜索树执行深度优先遍历。搜索树是在搜索过程中生成的,它表示为了找到解决方案可能必须检查的其他选择。在搜索树中扩展节点的方法通常称为分支策略,文献中已经提出并研究了几种替代方法(参见4.2节)。如果在算法执行的某一点生成了节点,则回溯算法将访问visits该节点。约束用于检查节点是否可能导致CSP的解决方案,以及修剪不包含解决方案的子树。如果搜索树中的一个节点不能提供解决方案,那么它就是一个死端deadend。

朴素回溯算法(naive backtracking algorithm, BT)是所有更复杂回溯算法的起点(见表4.1)。在BT搜索树中,0层的根节点是赋值的空集,j层的节点是赋值集{x1 = a1,…xj = aj}。在搜索树中的每个节点上,都会选择一个未实例化的变量,该节点之外的分支由所有可能的方法组成,这些方法通过实例化变量及其域中的值来扩展节点。分支表示可以为该变量做出的不同选择。在BT中,在节点上只检查没有未实例化变量的约束。如果约束检查失败(约束不满足),则尝试当前变量的下一个域值。如果没有剩余的域值,BT将回溯到最近实例化的变量。如果最后一个变量实例化后,所有约束检查都成功,那么就会找到解决方案。

图4.1显示了由朴素回溯算法(BT)为6皇后问题生成的回溯树的一个片段。节点上的标签是该节点上作业集的短基。例如,标记为25的节点由赋值集{x1 = 2,x2 = 5}组成。白点表示没有实例化变量的所有约束都得到满足的节点(没有一对皇后相互攻击)。黑点表示一个或多个约束检查失败的节点。(阴影和虚线箭头的原因在4.5节中解释。)为了简单起见,我假设了一个静态的实例化顺序,在这个顺序中,变量xi总是在搜索树的第I级被选择,并且值是按照顺序1、…、6分配给变量的。

猜你喜欢

转载自blog.csdn.net/weixin_38354912/article/details/84768945