0

x is a variable with lower and upper bounds 0 and 20.

x_is_in_the_defined_domain is a bool variable indicating what its name tells.

The defined_domain is [1, 3], [5, 7].

We can link x and x_is_in_the_defined_domain by finding its complementary set (domain) of intervals [0], [4], [8, 20].

from ortools.sat.python import cp_model

model = cp_model.CpModel()

x = model.NewIntVar(0, 20, 'x')
x_is_in_the_domain = model.NewBoolVar('indicator')

a_domain = cp_model.Domain.FromIntervals([[1, 3], [5, 7]])
b_domain = cp_model.Domain.FromIntervals([[0], [4], [8, 20]])

model.AddLinearExpressionInDomain(x, a_domain).OnlyEnforceIf(x_is_in_the_domain)
model.AddLinearExpressionInDomain(x, b_domain).OnlyEnforceIf(x_is_in_the_domain.Not())

solver = cp_model.CpSolver()
status = solver.Solve(model=model)

I doubt if my approach is unnecesssary and wonder if there is any more 'built-in' way of doing this?

John
  • 1,779
  • 3
  • 25
  • 53

1 Answers1

1

So the answer is that no, there is not Not() of a linear constraint in domain. The good news is that complementing a domain can be automated:

print(a_domain)
print(b_domain)
print(a_domain.Complement())
print(a_domain.Complement().IntersectionWith(cp_model.Domain(0, 20)))

outputs

[1,3][5,7]
[0][4][8,20]
[-9223372036854775808,0][4][8,9223372036854775807]
[0][4][8,20]
Laurent Perron
  • 8,594
  • 1
  • 8
  • 22