我正在尝试使用SAT Solver来解决组合问题。
这涉及以下步骤:
这适用于我的小样本。但对于更具挑战性的解决方案,SAT解算器需要数小时甚至数天才能获得SAT / UNSAT结论。我尝试调整编码以得到解决方案。但是我在编码中付出的努力越多,我的编码实际上就越不确定(即“可满足等价”)。
从布尔表达到CNF的步骤相当复杂,在可管理数量的子句和变量方面是有效的。等待SAT求解器的年龄是很痛苦的,并且不确定时间花在正确的轨道上。
布尔表达式可能有误。因此,我想验证CNF实际上代表的是原始问题而不仅仅是布尔表达式。
我的问题:
我如何验证给定编码是否是原始布尔表达式的有效表示?
从文献中,我已经知道了一些问题的解决方案,我可以将其转化为变量赋值,以便在编码过程中获得信任。但由于Tseitin encoding,我的CNF中的大多数变量都是辅助(切换)变量。没有Tseitin encoding,我的CNF将太大而无法解决。因此,我不能简单地检查已知解决方案是否满足每个CNF条款。
我尝试使用cnf2aig将CNF转换回布尔表达式,但该工具仍处于起步阶段。在不切换变量的情况下,可以直接检查主要问题变量的布尔表达式的分配。
有一些关于“CNF到电路”方法的出版物,但它们都没有提供可用的工具。
有没有最佳做法来完成这样的检查?
答案 0 :(得分:1)
所以你要问的是:
给定布尔表达式B和CNF C,有没有办法判断它们是否满足?
或换句话说:
存在满足B但不满足C的模型,或满足C但不满足B的模型?如果不存在这样的模型,那么两者都是不可满足的。
我对该问题的解决方案如下:
我会使用一个已知良好的软件(例如您未优化的代码或第三方工具)从布尔表达式生成已知良好的CNF D.
使用Tseitin从C和D生成!B的CNF。将CNF解释为C的和和(析取的结合)的乘积并反转整个表达式。让我们将得到的CNF C'称为C的倒数,D'称为D的倒数。
因此满足C的模型不满足C',反之亦然。类似于D和D'。
使用SAT求解器查找满足C和D'的模型。这样的模型会满足C但不满足B.
使用SAT求解器查找满足C'和D的模型。这样的模型会满足B但不满足C.
如果步骤3和4.两者都没有产生模型(不饱和),那么你已经证明B和C是完全可以满足的。
步骤3.和4.很容易。只需创建一个包含两个CNF中所有子句的大型CNF。来自B的所有变量必须在两个CNF中使用相同的文字进行编码,并且辅助变量必须从不同的池中分配。
根据您的问题,解决步骤3和4可能在计算上非常昂贵。因此,如果您可以将问题拆分为可以彼此独立验证的较小块,则此方法可能是可行的。
我希望有所帮助。您已经说过要尝试确保优化是正确的,因此您应该拥有一个已知良好的实现。否则你可以使用我编写的库作为外部参考:
https://github.com/cliffordwolf/yosys/tree/master/libs/ezsat
这个库生成的CNF效率不高!但它经过了很好的测试..