Tldr
Watched Propagation of 0-1 Integer Linear Constraints
Summary
Efficient unit propagation for clausal constraints is a core building block of conflict-driven clause learning (CDCL) Boolean satisfiability (SAT) and lazy clause generation constraint programming (CP) solvers. Conflict-driven pseudo-Boolean (PB) solvers extend the CDCL paradigm from clausal constraints to 0-1 integer linear constraints, also known as (linear) PB constraints. For PB solvers, many different propagation techniques have been proposed, including a counter technique which watches all literals of a PB constraint. While CDCL solvers have moved away from counter propagation and have converged on a two watched literals scheme, PB solvers often simultaneously implement different propagation algorithms, including the counter one.
Motivation
在基于 CDCL 的 PB 求解中,随着 PB 学习约束库在求解过程的增长,PB 的约束传播成为搜索过程中最主要的耗时组件。
Galena
求解器研究了一种高度复杂的用于伪布尔约束的观察字,但最终采用了三层式方法:子句和基数约束通过专门的观察字传播处理,而通用 PB 约束的传播则通过计数器传播实现,该方法能同时观察所有文字。Pueblo
求解器最初采用相同的三层方法,但后来选择了一个定制的观察字方法。Sat4J
默认情况下也使用三层架构,但对于一般 PB 约束使用类似于 Galena
的方法。最后,RoundingSat
采用了观察传播,与 Pueblo
和原始 Galena
方法有相似之处,但增加了自己的一些方法。
然而目前基于观察字的传播依然是一个 open problem,因为我们还没找到一种高效的惰性数据结构来观察约束中的文字,因此本文提出了一种高效的基于观察的 PB 约束传播算法。
记号与前置知识
我们在这里沿用 前文 中度以及 的定义,例如对约束 ,在最开始,其部分赋值 ,因此
我们首先解释 Counter PB 传播的工作原理,由上面的 我们可知:
若当前有文字 未被赋值,且其在约束 中的系数为 ,那么我们有
如果这个不等式成立,那么我们当 为真时 才能够成立,此时,我们说我们传播了 ,而如果存在不等式 成立,那么我们说此时发生了冲突,然后求解器会进入冲突分析的阶段。
我们通过先前的例子来解释这个传播过程:
- 此时我们决策 成立,那么 ,此时
- 对于文字 ,我们有 成立,那么 被传播为真 ,此时不会有任何 减小发生,于是传播会停止
- 下一次我们决策文字 ,那么此时 ,
- 对于文字 ,我们有 成立,于是此时我们直接传播 ,并满足了约束
缺陷
考虑这个例子 ,如果我们最开始赋值的是其中任意一个 ,那么 ,而每次我们决策 时, 最多减少 1,在这么多次下降时,我们永远无法进行传播(因为如果我们一直没有将 赋值为假的话 ,没办法使得 成立)
基于观察字的传播
我们将 SAT 中的观察字技术引入到 PB 中来,具体而言,我们引入了一个集合 来表示约束 中的观察字集合,并定义了另一个分数:
显然,对于任意一个约束 ,我们都有 ,当且仅当所有未被观察的文字都被赋值为假时,上式能够取等。
现在,我们定义一些记号,用于我们算法的描述:
- 表示约束 中系数的最大值
- 一条约束 ,我们通过一个三元组 来表示,其中: 3. 表示由一个三元组 组成的有序序列(顺序为 的递减顺序),这里的 表示系数, 表示文字, 标注是否为观察字 4. 为正数,表示约束 的度 5. 为上文中的
-
- 的状态我们用一个四元组 来表示,其中:
- 是传播索引,满足
- 是一个函数,将文字映射到约束集合的函数,例如 当且仅当
- 表示一个局部赋值,其中
- 传播索引表示当前赋值的哪一部分已经被传播,也就是在只有 中的观察字需要被检查是否需要传播
现在,我们正式开始描述算法,在初始时,没有约束被传播/冲突,且 ,我们考虑 ,观察字集合为
假设求解器的决策序为 ,在每次决策后,我们会调用 processWatches
来处理观察字:
可以发现,由于 都不是观察字,因此我们不会进入传播的过程,只能得到 此时,我们决策文字 ,得到
那么,我们首先将 ,由于 是 的观察字,那么我们减少 并进行传播,我们传入的
而 ,我们进入 while
迭代,并选择那些不是观察字且没有被赋值为假的变量所对应的文字,将这些文字设置为观察字。在这里,我们会引入新的观察字 ,此时
下一步,我们将 从观察字列表中去除,并结束这一次的传播。最终,我们得到新的观察字列表:
接着,我们决策 ,从而得到赋值为 ,然后运行 processWatches
得到 ,然后调用函数 propagate(C, 3)
此时,我们发现无法找到新的观察字使得 ,那么我们考虑当前约束可能能进行传播赋值,此时,我们通过检查当前约束中是否存在那些没有赋值的文字,将其赋值为真。显然这里我们做不了任何传播,于是直接退出。
Hint
我们在这里通过 来优化:我们先前所说,项在约束中是按照 递减排序的,而这里我们值需要传播那些只要赋值为真,就能保证约束为真的文字,通过前面的条件,我们能够避免扫描整个约束中的文字
回跳函数如图所示