0

I have written a constraint programming model using Google OR Tools in Python, which uses CP solver. I need to run that model multiple times, and in each run I modify constraints. Currently, I create the model object from scratch, every time I want to run the model. Is there anyway, I can modify variables/constraints of an existing model, so that I don't need to build the model from scratch everytime?

To give better context, please consider the below sample model.

from ortools.sat.python import cp_model
model = cp_model.CpModel()
num_vals = 3
a = model.NewIntVar(0, num_vals -1, 'a')
b = model.NewIntVar(0, num_vals -1, 'b')
c = model.NewIntVar(0, num_vals -1, 'c')
model.Add(a == b)
solver = cp_model.CpSolver()
solver.Solve(model)

Now, in the 2nd run of the problem, I want to do following changes.

  1. Change the upper bound of variable c to 5
  2. Delete the constraint a==b
  3. Create a new constraint a==c

How can this be achieved without building the model from scratch?

Devarshi
  • 23
  • 4

2 Answers2

6

Here's the code following Laurent's answer:

# 1. change c upper bound to 5
c.Proto().domain[:] = []
c.Proto().domain.extend(cp_model.Domain(0, 5).FlattenedIntervals())
# 2. delete a == b
# assuming that you did a_eq_b = model.Add(a == b)
a_eq_b.Proto().Clear()
Stradivari
  • 2,626
  • 1
  • 9
  • 21
3

First, you can have a look at this page.

The basic idea is that you can manipulate the underlying protobuf stored in the cp_model class. The only rule is that you should not delete a variable as they are referenced by index in other constraints.

To delete a constraint, just call Clear() on it (see this link). To add a constraint, use the normal API. To change the domain of a variable, you can manipulate its domain. Be aware that the domain is stored as a flattened list of disjoint closed intervals.

Laurent Perron
  • 8,594
  • 1
  • 8
  • 22