问题描述
我有这个简单的CP程序:
from ortools.sat.python import cp_model
horizon = 5
model = cp_model.CpModel()
A = model.NewIntvar(1,horizon,'A')
C = model.NewIntvar(1,'C')
D = model.NewIntvar(1,'D')
E = model.NewIntvar(1,'E')
model.Add(max(A+C+D,A+D+E) > max(A+C+E,C+E+D))
solver = cp_model.cpsolver()
status = solver.solve(model)
if status in (cp_model.FEASIBLE,cp_model.OPTIMAL):
print('status: ',status)
print('A: ',solver.Value(A))
print('C: ',solver.Value(C))
print('D: ',solver.Value(D))
print('E: ',solver.Value(E))
else:
print('Could not solve')
运行它会给我:
status: 4
A: 5
C: 1
D: 1
E: 1
鉴于提供的约束,这是不正确的。我在做错什么吗?
解决方法
您不能将min
,max
,or
,and
与ortools变量一起使用,因为它们会覆盖__ge__
,__lt__
创建线性表达式的神奇方法。
在这种情况下,您必须创建4个新变量(每个总和1个)和受model.AddMaxEquality
约束的另外2个变量。您还可以使用2个布尔值来设置2个最大变量。
编辑:
acd = model.NewIntVar(1,3 * horizon,"ACD")
model.Add(acd == A + C + D)
ade = model.NewIntVar(1,"ADE")
model.Add(ade == A + D + E)
ace = model.NewIntVar(1,"ACE")
model.Add(ace == A + C + E)
ced = model.NewIntVar(1,"CED")
model.Add(ced == C + E + D)
max1 = model.NewIntVar(1,"max1")
max2 = model.NewIntVar(1,"max2")
model.AddMaxEquality(max1,[acd,ade])
model.AddMaxEquality(max2,[ace,ced])
model.Add(max1 > max2)
,
为了记录,请遵循Stradivari的答案:
#!/usr/bin/env python3
from ortools.sat.python import cp_model
horizon = 5
model = cp_model.CpModel()
A = model.NewIntVar(1,horizon,'A')
C = model.NewIntVar(1,'C')
D = model.NewIntVar(1,'D')
E = model.NewIntVar(1,'E')
#model.Add(max(A+C+D,A+D+E) > max(A+C+E,C+E+D))
acd = model.NewIntVar(1,ced])
model.Add(max1 > max2)
solver = cp_model.CpSolver()
status = solver.Solve(model)
if status in (cp_model.FEASIBLE,cp_model.OPTIMAL):
print('status: ',status)
print('A: ',solver.Value(A))
print('C: ',solver.Value(C))
print('D: ',solver.Value(D))
print('E: ',solver.Value(E))
print('ACD: ',solver.Value(acd))
print('ADE: ',solver.Value(ade))
print('max1: ',solver.Value(max1))
print('ACE: ',solver.Value(ace))
print('CED: ',solver.Value(ced))
print('max2: ',solver.Value(max2))
else:
print('Could not solve')
可能的输出:
%./max.py
status: 4
A: 2
C: 1
D: 2
E: 1
ACD: 5
ADE: 5
max1: 5
ACE: 4
CED: 4
max2: 4