我正在使用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中使用增量求解。
我的最后一个问题是:这是使求解程序的执行时间最少的正确方法,还是有其他/更好的方法?
答案 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
就可以更快:它完全取决于启发式方法和所涉及的决策过程,而后者取决于当前的问题。