问题描述
我有这个:
import constraint
p = constraint.Problem()
t = [0,5]
c = [3,7]
s = range(len(t))
n = 12
p.addVariables([str(i) for i in s],range(n))
p.addConstraint(lambda x: (x+t[0])%n in c,('0'))
p.addConstraint(lambda x: (x+t[1])%n in c,('1'))
l = [list(i.values()) for i in p.getSolutions()]
print(l)
然后输出:
[[7,10],[7,2],[3,2]]
但我想在循环中添加约束,所以我这样做而不是两行p.addConstraint
:
for i in s:
p.addConstraint(lambda x: (x+t[i])%n in c,(str(i)))
我希望这会给出相同的输出,但我得到了这个:
[[10,[10,[2,2]]
我错过了什么?
解决方法
您可以使用创建函数的函数,然后在 for 循环中创建函数并将它们添加为约束。
import constraint
p = constraint.Problem()
t = [0,5]
c = [3,7]
s = range(len(t))
n = 12
p.addVariables([str(i) for i in s],range(n))
def generate_constrained_func(t,n,c):
def constraint_func(x):
return ((x+t)%n in c)
return constraint_func
for idx,t_constraint in enumerate(t):
p.addConstraint(generate_constrained_func(t_constraint,c),(str(idx)))
l = [list(i.values()) for i in p.getSolutions()]
print(l)
输出:
[[7,10],[7,2],[3,2]]
,
我确实设法用 eval
解决了它,但我听说这是一个危险的函数,所以我试图避免它。但如果没有人想出更好的方法,那就是我使用的:
for i in s:
eval('p.addConstraint(lambda x: (x+t[%d])%%n in c,(str(i)))' % i)
并没有解释为什么问题中的代码不起作用,我仍然对此感到好奇。