我正在使用SAT解算器对问题进行编码,作为SAT实例的一部分,我具有布尔变量,其中这些变量中的一个应该为true,其余的应该为false 。(我有时将其描述为“一次性”编码。)
我想在SAT中编码约束“一个必须为true”。编码此约束以使SAT求解器尽可能高效运行的最佳方法是什么?
我可以看到许多方法来编码此约束:
成对约束。我可以为所有添加成对约束以确保至多一个为true,然后添加以确保至少一个为true 。我,Ĵ X 我X 1 ∨ X 2 ∨ ⋯ ∨ X Ñ
这将添加子句,并且没有额外的布尔变量。
二进制编码。 我可以引入新的布尔变量来表示(以二进制形式)一个整数,使得(添加一些布尔约束以确保在所需范围内)。然后,我可以添加一些约束来强制是tree,而所有其他都是false。换句话说,对于每个,我们添加强制执行子句。我1,我2,... ,我LG的Ñ我1 ≤ 我≤ Ñ 我X 我X Ĵ Ĵ 我= Ĵ ⇔ X Ĵ
这增加了子句,我不知道有多少个额外的布尔变量。
计算真实值的数量。 我可以实现一个布尔加法器电路树,并要求,将每个视为0或1而不是false或true,然后使用Tseitin变换将电路转换为SAT子句。一棵半加法器树就足够了:将每个半加法器的进位输出限制为0,并将该树中最后一个半加法器的最终输出限制为1。可以选择任何形状的树(平衡的二叉树,或不平衡的树,等等。x i
这可以在门中完成,因此可以添加子句和新的布尔变量。Θ (n )Θ (n )
这种方法的一个特例是引入布尔变量,以使应该包含。可以通过添加以下子句,和来强制实施此意图(其中,将视为a false的同义词。接下来,我们可以为添加限制。这基本上等效于半加法树的Tseitin变换,其中树具有最大的不平衡形状。ÿ 我X 1 ∨ X 2 ∨ ⋯ ∨ X 我ÿ 我 ∨ ¬ X 我ÿ 我 ∨ ¬ ÿ 我- 1 ¬ ÿ 我 ∨ X 我 ∨ ÿ 我- 1个 Ÿ 0我= 1 ,... ,ñ ¬ ÿ 我 ∨ ¬ X 我+我=1,2,...,ñ-1
蝴蝶网。我可以在位上构建蝶形网络,将位输入约束为,将位输出约束为,并将每个2位蝶形门视为独立的门,交换或不交换其输入,并根据不受约束的新的布尔变量决定要执行的操作。然后,我可以应用Tseitin变换将电路转换为SAT子句。n 000 ⋯ 01 n x 1 x 2 ⋯ x n
这需要门,因此添加了子句和新的布尔变量。Θ (n lg n )Θ (n lg n )
还有其他我忽略的方法吗?我应该使用哪一个?有没有人对此进行过测试或尝试过,还是有任何经验?子句的数量和/或新的布尔变量的数量是否是评估此问题对SAT求解器性能影响的良好替代指标,或者如果不是,您将使用哪种指标?
我只注意到这个答案对强制基数约束SAT,即,实施该约束恰好一些参考了出来变量是真实的。因此,我的问题归结为的特殊情况。也许有关基数约束的文献将有助于阐明我的问题。n k = 1