Проблемы с добавлением ограничений в цикл
У меня есть это:
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, 10], [3, 2]]
Но я хочу добавить ограничения в цикл, поэтому я сделал это вместо двух
p.addConstraint
линии:
for i in s:
p.addConstraint(lambda x: (x+t[i])%n in c, (str(i)))
Я ожидал, что это даст тот же результат, но вместо этого получил следующее:
[[10, 10], [10, 2], [2, 10], [2, 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, n, c), (str(idx)))
l = [list(i.values()) for i in p.getSolutions()]
print(l)
Выход:
[[7, 10], [7, 2], [3, 10], [3, 2]]
Мне удалось решить это с помощью
eval
, но я слышал, что это опасная функция, поэтому стараюсь ее избегать. Но если никто не придумает ничего лучше, я использую вот что:
for i in s:
eval('p.addConstraint(lambda x: (x+t[%d])%%n in c, (str(i)))' % i)
Это не объясняет, почему код в вопросе не работает, и мне все еще любопытно.