序言:我正在玩z3py并试图实现一些全局约束的分解,例如: nvalue(n, x)
确保向量/数组n
中有不同数量的x
个不同值。约束编程系统往往有可能提取决策变量的下限和上限 - 我碰巧非常喜欢这些全局约束。
我现在的问题是,是否可以获得变量的下限和上限,定义为Int
,IntVector
或Array("x", IntSort(), IntSort())
?
(我已经对全局约束进行了一些分解 - 请参阅http://hakank.org/z3/ - 但只要分解需要上限/下限,我就必须在方法调用中添加这些限制。)
这是一个例子。请注意,它使用http://hakank.org/z3/z3_utils_hakank.py中定义的一些方便方法,简化了约束编程模型的端口;抱歉,如果这令人困惑。
关键是必须将min_value
和max_value
两个值明确添加到方法nvalue
。
from z3_utils_hakank import *
#
# ensure that there are exactly m distinct values in x
#
def nvalue(sol, m, x, min_val,max_val):
n = len(x)
sol.add(m == Sum([ If(Sum([ If(x[j] == i,1,0) for j in range(n)]) > 0,1,0) for i in range(min_val, max_val+1)]))
sol = Solver()
n = 5
min_val = 1 # <--
max_val = n # <--
# variables
m = makeIntVar(sol,"m",0,n) # number of distinct values
x = makeIntVector(sol,"x",n, 1,n)
# constraints
nvalue(sol,m,x,min_val, max_val)
# solutions
num_solutions = 0
while sol.check() == sat:
num_solutions += 1
mod = sol.model()
print "m:", mod.eval(m)
print "x:", [mod.eval(x[i]) for i in range(n)]
print
getDifferentSolution(sol,mod,x)
print "num_solutions:", num_solutions
如果它很棒,nvalue
的方法定义可以写成这样的东西:
def nvalue(sol, m, x):
n = len(x)
min_val = sol.min_val(x)
max_val = sol.max_val(x)
sol.add(m == Sum([ If(Sum([ If(x[j] == i,1,0) for j in range(n)]) > 0,1,0) for i in range(min_val, max_val+1)]))
即。使用某些z3py函数,例如sol.min_value(x)
和sol.max_val(x)
。