Z3PY速度非常慢,有很多变量?

Z3PY速度非常慢,有很多变量?,z3,solver,smt,z3py,Z3,Solver,Smt,Z3py,我一直在使用Z3PY中的优化器,并且在我的项目中只使用Z3int和(x=1) 对于i in(需求): 解算器。添加(i每个基准都是唯一的,不可能想出一个在所有情况下都同样适用的好策略。但是您描述的场景非常简单,可以处理。性能问题来自这样一个事实:Distinct创建了太多的不平等(二次型)对于解算器,随着变量数量的增加,优化器很难处理它们 根据经验,如果可以的话,应该避免使用Distinct。对于这种特殊情况,对变量施加严格的排序就足够了。(当然,这可能并不总是可能的,这取决于其他约束条件,但您

我一直在使用Z3PY中的优化器,并且在我的项目中只使用Z3int和(x 我创建了26个Z3整数。然后我添加了硬约束,即它不应小于1或大于26。此外,所有数字必须是唯一的。没有添加任何其他约束。 换句话说,解算器将找到的解是一个简单的顺序[1,2,3,4,5…,最多26]。以解算器发现的方式排序

我的意思是这是一件简单的事情,除了我提到的那些约束之外,实际上没有约束。解算器可以在0.4秒或类似的时间内解决这个问题,快速且足够。这是意料之中的。但是如果我把变量的数量增加到49(当然现在的限制是它不应该小于1或大于49),求解器需要大约1分钟的时间来求解。对于这么简单的任务来说,这似乎真的很慢?应该是这样吗,有人知道吗?时间复杂性真的大大增加了吗

(我知道我可以在这个特定的实验中使用Solver()而不是Optimizer(),它会在一秒钟内解决,但实际上我需要用Optimizer来完成,因为我有很多软约束要处理。)

编辑:为我的示例添加一些代码

I declare an array with Z3 ints that I call "reqs".
The array is consisting of 26 variables in one example and 49 in the other example I am talking about.

solver = Optimize()

 for i in (reqs):
     solver.add(i >= 1)

for i in (reqs):
    solver.add(i <= len(reqs))

    d = Distinct(reqs)
    solver.add(d)

res = solver.check()
print(res)
我声明了一个包含Z3整数的数组,我称之为“reqs”。
这个数组在一个例子中由26个变量组成,在另一个例子中由49个变量组成。
解算器=优化()
对于i in(需求):
求解器。添加(i>=1)
对于i in(需求):

解算器。添加(i每个基准都是唯一的,不可能想出一个在所有情况下都同样适用的好策略。但是您描述的场景非常简单,可以处理。性能问题来自这样一个事实:
Distinct
创建了太多的不平等(二次型)对于解算器,随着变量数量的增加,优化器很难处理它们

根据经验,如果可以的话,应该避免使用
Distinct
。对于这种特殊情况,对变量施加严格的排序就足够了。(当然,这可能并不总是可能的,这取决于其他约束条件,但您描述的内容似乎可以从这个技巧中获益。)因此,我将这样编写代码:

从z3导入*
需求=[Int('i_ud'%i'),用于范围(50)内的i]
解算器=优化()
对于需求中的i:

solver.add(i>=1,i每个基准都是唯一的,不可能想出一个在所有情况下都同样适用的好策略。但是您描述的场景非常简单,可以处理。性能问题来自于
Distinct
创建了太多的不等式(二次型)对于解算器,随着变量数量的增加,优化器很难处理它们

根据经验,如果可以的话,应该避免使用
Distinct
。对于这种特殊情况,对变量施加严格的排序就足够了。(当然,这可能并不总是可能的,这取决于其他约束条件,但您描述的内容似乎可以从这个技巧中获益。)因此,我将这样编写代码:

从z3导入*
需求=[Int('i_ud'%i'),用于范围(50)内的i]
解算器=优化()
对于需求中的i:

求解器。添加(i>=1,i优化引擎的性能不被期望;它们也不会像现有的解算器那样经常受到关注和加速。但是每个基准都是不同的,所以你应该发布具体的例子,看看能做些什么,如果有的话。我现在已经将代码添加到原来的帖子中。但是,是的,我理解。但是感觉很好有点奇怪,当从26个变量更改为49个变量时,速度要慢得多它需要一毫秒或其他时间。在这里使用Z3PY需要一分钟,有49个变量。优化引擎预计不会有性能;它们也不会像现有的解算器那样经常受到关注和加速。但是每个基准都是不同的,所以你应该发布具体的例子,看看能做些什么。我有e现在将代码添加到原始帖子中。但是,是的,我理解。但是当从26个变量更改为49个变量时,速度会慢得多,这感觉有点奇怪。使用Yices(用SMTlib2编写和执行)它需要一毫秒左右。在这里使用Z3PY需要一分钟,有49个变量。非常感谢!现在它在不使用Distinct的情况下速度非常快。我使用了数百个软约束。但有一个问题。我运行了很多次,得到了很多值,然后计算中值。看看它的性能如何。在我更改t之前代码中,我使用了:set_option('smt.random_seed',random.randint(0,2**8)),这样它就不会在每次执行时产生完全相同的结果。但是现在,当不使用distinct时,这似乎不起作用。我现在在每次执行中都会得到完全相同的结果。你知道怎么做吗?你不应该真正依靠random seed来获得结果“不同的"模型。这种方法非常容易出错,因为它对解算器的内部结构非常敏感,即使看起来相对简单的更改也会停止工作。我建议使用随机数来调整变量的顺序。在我的代码中,有一个严格的顺序:
i0
等。在Python sid中使用随机种子e以获得不同的排序:
i43
等;而不是依赖解算器。(注意,这是
$ time python a.py
sat
[i_39 = 40,
 i_3 = 4,
 ...
 i_0 = 1,
 i_2 = 3]
python a.py  0.27s user 0.09s system 98% cpu 0.365 total