问题
I want three 1s to appear in the shift array,I wrote the following code:
model = cp_model.CpModel()
solver = cp_model.CpSolver()
shifts = {}
for i in range(5):
shifts[(i)] = model.NewIntVar(0, 3, "shifts(%i)" % i)
for i in range(5):
model.Add(sum([shifts[(i)]==1 for i in range(5) ]) == 3)
solver = cp_model.CpSolver()
status = solver.Solve(model)
for i in range(5):
print(solver.Value(shifts[(i)]))
But it return: TypeError: unsupported operand type(s) for +: 'int' and 'BoundedLinearExpression'
Can anyboday help me ,please!
回答1:
Edit: As @Laurent Perron says, it is probably better to model your problem using booleans.
model = cp_model.CpModel()
solver = cp_model.CpSolver()
shifts = {}
values = range(3+1)
for i in range(5):
for j in values:
shifts[i, j] = model.NewBoolVar(f"{i} == {j}")
# for each shift only 1 value is true
model.Add(sum(shifts[i, j] for j in values) == 1)
# number of booleans where value is 1 == 3
model.Add(sum(shifts[i, 1] for i in range(5)) == 3)
solver = cp_model.CpSolver()
status = solver.Solve(model)
for i in range(5):
for j in values:
if solver.Value(shifts[i, j]):
print(i, "==", j)
Original answer:
You can't sum constraints, create one boolvar per position, link the variables using model.Add(shifts[i]==1).OnlyEnforceIf(ones[i])
and constraint sum(ones)
instead.
from ortools.sat.python import cp_model
model = cp_model.CpModel()
solver = cp_model.CpSolver()
shifts = {}
ones = {}
for i in range(5):
shifts[i] = model.NewIntVar(0, 3, "shifts(%i)" % i)
ones[i] = model.NewBoolVar("")
model.Add(shifts[i] == 1).OnlyEnforceIf(ones[i])
model.Add(shifts[i] != 1).OnlyEnforceIf(ones[i].Not())
model.Add(sum(ones.values()) == 3)
solver = cp_model.CpSolver()
status = solver.Solve(model)
for i in range(5):
print(solver.Value(shifts[(i)]))
来源:https://stackoverflow.com/questions/62726632/how-can-i-use-cpmodel-to-make-three-1s-appear-in-a-1d-array-or-tools