使用线性算法和Z3的多重分区

时间:2012-01-29 03:55:29

标签: z3

我必须将多个分区分成两组,其总和是相等的。例如,给定multiset:

1 3 5 1 3 -1 2 0

我会输出两组:

1) 1 3 3
2) 5 -1 2 1 0

两者总和为7。

我需要使用Z3(smt2输入格式)和“线性算术逻辑”来执行此操作,其定义为:

formula : formula /\ formula | (formula) | atom
   atom : sum op sum
     op : = | <= | <
    sum : term | sum + term
   term : identifier | constant | constant identifier

老实说,我不知道从哪里开始,任何建议都会受到赞赏。

问候。

2 个答案:

答案 0 :(得分:1)

这是一个想法:

1-为每个元素创建一个0-1整数变量c_i。如果element在第一个集合中,则c_i为零,如果在第二个集合中,则为1。您可以通过说0 <= c_ic_i <= 1来实现这一点。

2-第一组中元素的总和可以写为1*(1 - c_1) + 3*(1 - c_2) + ... +

3-第二组中元素的总和可以写为1*c1 + 3*c2 + ...

答案 1 :(得分:1)

虽然SMT-Lib2非常具有表现力,但它并不是最容易编程的语言。除非您有必要直接在SMTLib2中编码,否则我建议您查看具有更高级别绑定的其他语言。 SMT求解器。例如,Haskell和Scala都有库,允许您在更高级别编写SMT解算器脚本。以下是使用Haskell解决问题的方法,例如:https://gist.github.com/1701881

这个想法是这些库允许您在更高级别进行编码,然后在幕后为您执行必要的SMT求解器转换和查询。 (如果您确实需要了解问题的SMTLib编码,您也可以使用这些库,因为它们通常带有必要的API来转储它们在查询解算器之前生成的SMTLib。)

虽然这些库可能无法提供Z3允许您通过SMTLib访问的所有内容,但它们更易于用于大多数感兴趣的实际问题。