z3:如何解决一组常量的组合?

时间:2017-10-21 00:38:23

标签: python z3 smt

我对数学并不十分精明,所以如果我在这里使用了错误的术语,请不要摧毁我。

我想用z3解决的问题是这样的:

x + y = z

假设x和z是整数。

其中y是一个常数数组,如(12,13,14,-13),可以使用,重用或不用作求解器。

我如何将其转换为z3的功能?我怀疑答案是为这些常量的每个可能组合生成一个约束,但我还没有看到一个像我想要做的那样的例子。

换句话说,我如何翻译许多编程访谈中发现的“总和组合”等问题,例如:

Finding all possible combinations of numbers to reach a given sum

https://leetcode.com/problems/combination-sum/description/

进入z3表示法?

非常精确的是,这个不清楚的部分是如何与数组选择选择的解决方案进行沟通,以及多少次次 em>喜欢它。

1 个答案:

答案 0 :(得分:3)

当然,对于任何SMT求解器来说,这都很容易。这是编码它的一种方法:

from z3 import *

s = Solver()
x = Int("x")
y = Int("y")
z = Int("z")

s.add(Or(y == 12, y == 13, y == 14, y == -13))
s.add(x + y == z)

while s.check() == sat:
    m = s.model ()
    if not m:
        break
    print m
    s.add(Not(And([v() == m[v] for v in m])))

请注意,有无限多个三元组可以满足这一特定约束条件,因此当您运行上述内容时,它将永远继续打印解决方案!

要解决找到总和为数字的数字子集,您可以进行类似的操作。对于每个元素声明一个布尔值。然后,编写一个求和表达式,它将所有数字相加,使得相应的布尔值为True,并断言此求和等于所需数量的约束。有趣的小运动,使用Z3再次很容易表达。如果你试一试并有问题,请随时提出进一步的问题。