如何使用 CpModel 使三个 1 出现在一维数组中?(或工具)



我希望移位数组中出现三个1,我编写了以下代码:

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)]))

但它返回: 类型错误: + 不支持的操作数类型:"int"和"有界线性表达式">

任何人都可以帮我吗,请!

编辑:正如@Laurent Perron所说,最好使用布尔值对问题进行建模。

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)

原答案:

您不能对约束求和,不能为每个位置创建一个布尔变量,而是使用model.Add(shifts[i]==1).OnlyEnforceIf(ones[i])和约束sum(ones)链接变量。

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)]))

最新更新