Search code examples
or-toolscpcp-sat

How to create a bool variable to indicate if another integer variable is between two specific values


In ortools cp-sat, how could we link an boolean decision variable to whether an integer variable value is between two given values.

from ortools.sat.python import cp_model


def get(x):
    return solver.Value(x)


model = cp_model.CpModel()
x_is_between_5_and_10 = model.NewBoolVar('x_is_between_5_and_10')
x = model.NewIntVar(0, 100, 'x')
model.Add(x == 7)
model.Add(x_is_between_5_and_10 == 1).OnlyEnforceIf(5 <= x).OnlyEnforceIf(x <= 10)
solver = cp_model.CpSolver()
status = solver.Solve(model=model)
print('x', get(x))
print('x_is_between_5_and_10', get(x_is_between_5_and_10))

Solution

  • Use:

    model.AddLinearConstraint(x, 5, 10).OnlyEnforceIf(x_is_between_5_and_10).
    model.AddLinearExpressionInDomain(x, cp_model.Domain.FromIntervals([[0, 4], [11, 100]])).OnlyEnforceIf(x_is_between_5_and_10.Not())
    

    Note you can also write

    model.AddLinearExpressionInDomain(x, cp_model.Domain.FromIntervals([[5, 10]])).OnlyEnforceIf(x_is_between_5_and_10)
    

    for the first equation. But it that case, AddLinearConstraint() is smaller.

    See the doc.