如何通过z3py

时间:2018-07-10 18:35:24

标签: z3 smt z3py

我正在使用Z3求解器的python API搜索优化的计划。它工作得很好,但有时即使是小型图形也很慢(尽管有时非常快)。其原因可能是我的调度问题的约束非常复杂。 我试图加快速度,偶然发现了一些有关增量求解的文章。 据我了解,您可以通过仅应用部分约束来使用增量求解来修剪某些搜索空间。

所以我的原始代码看起来像这样:

for constraint in constraint_set:
    self._opt_solver.add(constraint)
self._opt_solver.minimize(some_objective)
self._opt_solver.check()
model = self._opt_solver.mode()

我现在将其更改为以下内容:

for constraint in constraint_set:
    self._opt_solver.push(constraint)
    self._opt_solver.check()
self._opt_solver.minimize(some_objective)
self._opt_solver.check()
model = self._opt_solver.mode()

我基本上用“ push”命令代替了“ add”命令,并在每次推送后添加了一个check()。

首先,我的一般方法正确吗? 此外,我遇到了一个无法摆脱的异常:

self._opt_solver.push(constraint) TypeError: push() takes 1 positional argument but 2 were given

谁能给我一个提示,我在做什么错。也许还有一个z3py教程,它解释了(可能带有一些示例)如何在python api中使用增量求解。

我的最后一个问题是:这是使求解程序的执行时间最少的正确方法,还是有其他/更好的方法?

1 个答案:

答案 0 :(得分:1)

函数push不带参数。它会创建一个“回溯”点,您以后可以pop继续。看到这里:http://z3prover.github.io/api/html/classz3py_1_1_solver.html#abc4ae989afee7ad164844640537107d9

因此,push似乎根本不是您想要/不需要的。您只需简单地一对一添加约束,然后调用check。但是,我非常怀疑每次添加后进行检查是否会显着加快速度。特别是,优化求解器(与常规求解器相反)通常从头解决所有问题。 (请参见此处的相关讨论:https://github.com/Z3Prover/z3/issues/1577

关于增量式:python API自动为“增量式”。增量只是意味着能够多次调用命令check(),而求解器不会忘记之前看到的内容。 (即致电check,断言更多的事实,再次致电check;第二check将从一开始就考虑所有断言。)您不应该对以下内容做出任何假设这样一来,您结束时只需一次调用check就可以更快:它完全取决于启发式方法和所涉及的决策过程,而后者取决于当前的问题。