Algorithm 将项目指定给具有要素的组
我有一个问题,我是分配变量集。每个集合都有一个可以分配给它的变量限制,每个变量都可以分配给集合的某些子集 例如:Algorithm 将项目指定给具有要素的组,algorithm,set,combinations,z3,z3py,Algorithm,Set,Combinations,Z3,Z3py,我有一个问题,我是分配变量集。每个集合都有一个可以分配给它的变量限制,每个变量都可以分配给集合的某些子集 例如: a可以成套a或B b可以成套b c可以成套A或B d可以成套A 因此,我们可以有A:A,d;B:B,c或A:c,d;B:a,B(变量在集合中的顺序无关紧要) 我目前正在使用z3(在这里使用solve编写,也可以使用Solver表示)执行以下操作。根据下面的代码,如果a_in_a=True,则变量a处于设置a中 solve(If(a_in_B, 1, 0) + If(b_in_B,
可以成套a
或a
B
可以成套b
b
可以成套c
或A
B
可以成套d
A
A:A,d;B:B,c
或A:c,d;B:a,B
(变量在集合中的顺序无关紧要)
我目前正在使用z3(在这里使用solve编写,也可以使用Solver表示)执行以下操作。根据下面的代码,如果a_in_a=True
,则变量a
处于设置a
中
solve(If(a_in_B, 1, 0) + If(b_in_B, 1, 0) + If(c_in_B, 1, 0) <= 2,
If(a_in_A, 1, 0) + If(c_in_A, 1, 0) + If(d_in_A, 1, 0) <= 2,
If(a_in_A, 1, 0) + If(a_in_B, 1, 0) == 1,
If(b_in_B, 1, 0) == 1,
If(c_in_A, 1, 0) + If(c_in_B, 1, 0) == 1,
If(d_in_A, 1, 0) == 1)
不过,我还想输入其他功能,如
c
必须在a
之后设置。因此,我们将简化为A:A,d;B:B,c
。如何将这些需求添加到z3解算器表达式中(或以其他方式添加)?与任何编程任务一样,有许多方法可以解决此问题。我认为以下是z3py中最惯用的方法。注意内部Set
类型的使用,它由数组在内部建模。我选择整数作为集合的元素,但如果愿意,可以将其设置为枚举类型(或其他一些基类型):
从z3导入*
s=解算器()
a、 b,c,d=Ints('abcd')
等位基因=[a,b,c,d]
s、 添加(不同的(等位基因))
#我们有两套
A、 B=Consts('ab',SetSort(IntSort()))
所有集合=[A,B]
#一般要求:每个元素都属于某个集合:
对于等位基因中的e:
属于=假;
对于所有集合中的x:
归属=或(归属,IsMember(e,x))
s、 添加(属于)
#容量要求
sizeA,sizeB=Ints('sizeA-sizeB'))
s、 添加(设置大小(A,sizeA))
s、 添加(设置大小(B,大小B))
s、 加(sizeA啊,这很有帮助!我困惑的一个部分是,我该如何使问题特定要求
和c必须在a的集合之后的集合中
扩展到多个集合和多个要求。我知道你在回答中提到了后者,但我似乎无法理解。对于前者,我该如何格式化多个“或”语句(以循环方式),使得每个变量能够覆盖多个集合(我假定“或”中只能有2个项)?或
可以使用列表参数。我建议您尝试一下,如果卡住了,可以单独问一个关于堆栈溢出的特定问题,显示您尝试过的代码。此外,接受答案会告诉其他人问题已经解决。(请参阅答案旁边的“复选标记”)我在扩展你显示的代码时遇到了一些问题。我按照你的建议做了一个测试。我希望你能在回答这个问题时看一看,这样就有了背景。
solve(If(a_in_B, 4, 0) + If(b_in_B, 3, 0) + If(c_in_B, 3, 0) <= 6,
If(a_in_A, 4, 0) + If(c_in_A, 3, 0) + If(d_in_A, 3, 0) <= 7,
If(a_in_A, 4, 0) + If(a_in_B, 4, 0) == 4,
If(b_in_B, 3, 0) == 3,
If(c_in_A, 3, 0) + If(c_in_B, 3, 0) == 3,
If(d_in_A, 3, 0) == 3)
s.add(Implies(IsMember(a, A), IsMember(c, B)))
s.add(Not(IsMember(a, B))) # otherwise there wouldn't be a place to put c!
[A = Lambda(k!0, Or(k!0 == 1, k!0 == 4)),
b = 5,
a = 1,
d = 4,
sizeB = 2,
c = 3,
sizeA = 2,
B = Lambda(k!0, Or(k!0 == 3, k!0 == 5)),
Ext = [else -> 5]]
a = 1
b = 5
c = 3
d = 4
A = Lambda(k!0, Or(k!0 == 1, k!0 == 4)),
B = Lambda(k!0, Or(k!0 == 3, k!0 == 5)),