GabyLP
GabyLP

Reputation: 3781

Constraint Programming, how to add x[i] <= (max(x[:i]) + 1)

I'm building a model using or-tools CP tools. The values I want to find are placed in a vector X, and I want to add a constraint that says up to each position of X, the next position cannot have as a value something bigger than the maximum found until X[:i] + 1

It would be something like this:

X[i] <= (max(X[:i]) + 1)

Of course, I cannot add this as a linear constraint with a max(), and creating one extra feature for each value of X upper bound seems excessive and also I would need to minimize each one to make it the "max", otherwise those are just upper bounds that could be huge and not prune my search space (and I already have an objective function).

I already have an objective function.

I know that one trick to add for instance a min-max (min(max(x[i])) problem is to create another variable that is an upper bound of each x and minimize that one. It would be sth like this:

model = cp_model.CpModel()

lb =0; ub=0
model.NewIntVar(z, lb, ub)

for i in domain(X):
    model.NewIntVar(X[i], lb, up)
    model.Add(X[i] <= z)

model.Minimize(z)

In case you don't want to program this you can use the method in or-tools:

model.AddMaxEquality(z, X)

Now I want to add a constraint that at each value of X sets an upper limit which is the maximum value found until the previous x. It would be something like this:

X[i] <= max(X[:i]) + 1

I was thinking of replicating the previous idea but that would require creating a "z" for each x... not sure if that is the best approach and how much it will reduce my space of solutions. At the same time couldn't find a method in or-tools to do this.

Any suggestions, please?

PS: I already have as an objective function min(z) like it is in the example presented.

Example:

For instance, you can have as a result of the model: [0, 1, 2, 0, 2, 3]

But you shouldn't have:

[0, 1, 1, 2, 4] Since the max until X[:3] is 2, so the ub of X[4] should be 2 + 1.

Thanks!

Upvotes: 0

Views: 182

Answers (1)

Laurent Perron
Laurent Perron

Reputation: 11064

I have no specific hints except:

  • you need to experiment. One modeling trick may work on one kind of model and not on the other
  • make sure to use reuse the max variable at index i - 1. With X the array of variables and M the array of max, i.e. M[i] = max(X[0], .., X[i - 1])
    M[i] = max(M[i - 1], X[i - 1])
    X[i] <= M[i] + 1

Upvotes: 1

Related Questions