Search code examples
or-toolscp-sat

Constraint is not respected by or-tools


I have this simple CP program:

from ortools.sat.python import cp_model
horizon = 5
model = cp_model.CpModel()
A = model.NewIntVar(1, horizon, 'A')
C = model.NewIntVar(1, horizon, 'C')
D = model.NewIntVar(1, horizon, 'D')
E = model.NewIntVar(1, horizon, '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')

and running it gives me:

status:  4
A:  5
C:  1
D:  1
E:  1

which is incorrect given the constraint provided. Am I doing something wrong?


Solution

  • You can't use min, max, or, and with ortools variables, as they override the __ge__, __lt__ magic methods for creating linear expressions.

    In this case you have to create 4 new variables (1 for each sum) and 2 more variables constrained with model.AddMaxEquality. You could also use 2 booleans to set the 2 max variables instead.

    Edit:

    acd = model.NewIntVar(1, 3 * horizon, "ACD")
    model.Add(acd == A + C + D)
    ade = model.NewIntVar(1, 3 * horizon, "ADE")
    model.Add(ade == A + D + E)
    ace = model.NewIntVar(1, 3 * horizon, "ACE")
    model.Add(ace == A + C + E)
    ced = model.NewIntVar(1, 3 * horizon, "CED")
    model.Add(ced == C + E + D)
    
    max1 = model.NewIntVar(1, 3 * horizon, "max1")
    max2 = model.NewIntVar(1, 3 * horizon, "max2")
    model.AddMaxEquality(max1, [acd, ade])
    model.AddMaxEquality(max2, [ace, ced])
    model.Add(max1 > max2)