# Deleting containerized constraints

**URL:** https://discourse.julialang.org/t/deleting-containerized-constraints/21971
**Category:** Optimization (Mathematical)
**Created:** [March 17, 2019, 7:49pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971 "2019-03-17T19:49:57Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![Di11on](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/di11on/32/6352_2.png) [@Di11on](https://discourse.julialang.org/u/Di11on)
#### Post date: [March 17, 2019, 7:49pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/1 "2019-03-17T19:49:57Z")

</div>

Hi folks,

I am translating an electricity production cost model from GAMS to JuMP and am struggling to get reasonable model generation times. Generally these models consist of running 365 single-day optimisations to run a full year.

One of the things I am trying to do to improve model generation times is to identify which constraints don’t change and which need to be regenerated in each loop. The idea is then to delete the changed constraints and re-generate them. However, deleting the constraints is taking much more time than regenerating the full model.

Most constraints are containerized and generated similarly to this:

```julia
@constraint(model, con[i = 1:2, j = 2:3], i * x &lt;= j + 1)

```

To delete all of these, I have to do something lke this:

```julia
for c in con
    delete(model,c)
end

```

Some constraints are dimensioned by time and transmission node (48 x 500) and so this is taking a very long time. Is there a way better way of doing what I’m trying to do?

edit: just to add, I know there is `set_coefficient` and the hack with `.fix` to change the RHS… but what’s the point of a high level modeling language if I need to aggregate up the coefficients and constants myself - I may as well generate the MPS file from scratch in that case…

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [March 18, 2019, 1:37pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/2 "2019-03-18T13:37:58Z")

</div>

Please provide a minimum working example:

> [@Please read: make it easier to help you](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757):
>
> Welcome to the Julia Discourse! We are enthusiastic about helping Julia programmers, both beginner and experienced. This public service announcement (PSA) outlines best practices when asking for help. Following these points makes it easier for us to help you and more likely you’ll get a prompt, useful answer. Keywords are highlighted to make it easier to refer to specific points. Choose a descriptive title that captures the key part of your question, eg “plots with multiple axes” instead of …

In particular

- what solver are you using?
- how long does it take to rebuild the model vs delete the constraints?
- the way you are deleting in the loop is the correct syntax

> just to add, I know there is `set_coefficient` and the hack with `.fix` to change the RHS… but what’s the point of a high level modeling language if I need to aggregate up the coefficients and constants myself

Using `fix` to change the RHS is not a hack. It is the official way to change the RHS. Why?

- `@constraint(model, 2x + 1 <= 3)` Is the RHS `3` or `3-1=2`?
- `@constraint(model, 1 <= 2x + 1 <= 3)`. What is the RHS?

If you have lots of duplicate variables, it should be possible to restructure your code to simplify things.

---

<div class="post-metadata">

### Author: ![Di11on](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/di11on/32/6352_2.png) [@Di11on](https://discourse.julialang.org/u/Di11on)
#### Post date: [March 18, 2019, 2:25pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/3 "2019-03-18T14:25:01Z")

</div>

Thanks for the reply.

I’m using CPLEX at the moment as the solver.

Regarding a minimum working example, I really wanted to confirm that this was the correct way to delete a containerized constraint. There are many of these in the model so I can’t think of what a MWE would be.

```julia
for c in con
    delete(model,c)
end

```

Regarding the RHS thing - my understanding was always that the RHS was the constant term.

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [March 18, 2019, 2:30pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/4 "2019-03-18T14:30:06Z")

</div>

> I really wanted to confirm that this was the correct way to delete a containerized constraint.

I haven’t tried, but `delete.(model, con)` might work as well.

For a MWE, try to create a simple example where deleting the constraints takes a considerable amount of time. We can use that example as a benchmark to make improvements.

> Regarding the RHS thing - my understanding was always that the RHS was the constant term.

Constant term of the function (`2x + 1`) or constant term of the set (`<= 3`)? Here is a relevant JuMP issue if you want to discuss further: [Modify RHS (and define RHS) · Issue #1890 · jump-dev/JuMP.jl · GitHub](https://github.com/JuliaOpt/JuMP.jl/issues/1890)

---

<div class="post-metadata">

### Author: ![Di11on](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/di11on/32/6352_2.png) [@Di11on](https://discourse.julialang.org/u/Di11on)
#### Post date: [March 21, 2019, 10:54am UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/5 "2019-03-21T10:54:02Z")

</div>

So…

```julia
using JuMP,CPLEX

const C = 300000
const N = 100

function test_const()
    m=Model(with_optimizer(CPLEX.Optimizer, CPX_PARAM_SCRIND=0))
    coef = rand(C,N)
    @variable(m, 0 <= x[1:N] <= 1)
    @variable(m, 0 <= Θ <= 1000)
    val, time, = @timed @constraint(m, Θ .<= coef*x )
    println("time to create constraints: ", time)
    val, time, = @timed delete_constraints(m,x)
    println("time to delete constraints: ", time)
end

function delete_constraints(m,x)
    for con in x
        delete(m, con)
    end
end

test_const()

```

output:

```julia
time to create constraints: 21.936897123
time to delete constraints: 591.988164435

```

edit: and with `delete(m, x)`

```julia
ERROR: LoadError: MethodError: no method matching delete(::Model, ::Array{VariableRef,1})

```

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [March 21, 2019, 1:23pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/6 "2019-03-21T13:23:35Z")

</div>

> [@Di11on](#):
>
> and with `delete(m, x)`

It’s `delete.(m, x)`. Note the sneaky `.` after `delete` which tells Julia to use broadcasting.

Deleting constraints is an expensive operation, although @ndinsmore has been putting in great work improving this. See: [Improved constraint deletion performance by separating functions by ndinsmore · Pull Request #95 · JuliaOpt/LinQuadOptInterface.jl · GitHub](https://github.com/JuliaOpt/LinQuadOptInterface.jl/pull/95)

Could you try with `m = JuMP.direct_model(CPLEX.Optimizer(CPX_PARAM_SCRIND=0))`?

If you’re deleting large numbers of constraints, you might be better off just rebuilding the model from scratch?

---

<div class="post-metadata">

### Author: ![Di11on](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/di11on/32/6352_2.png) [@Di11on](https://discourse.julialang.org/u/Di11on)
#### Post date: [March 21, 2019, 2:00pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/7 "2019-03-21T14:00:39Z")

</div>

Thanks for that…`delete.(m, x)` produces the same timings, but I don’t believe you were suggesting otherwise.

As in my op, I am solving a model in a loop and am looking for ways to reduce the model building time. I was hoping to do this by rebuilding only the constraints that change which is a small subset of all the constraints in the model - but it doesn’t look like this approach will work.

So it looks like I will need to turn my attention to problem modification… but for this to be a real option, I do feel we need a solution that doesn’t involve adding dummy variables to the problem.

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [March 21, 2019, 2:09pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/8 "2019-03-21T14:09:54Z")

</div>

I’ve just realized that `delete_constraints(m,x)` is actually deleting variables? This _is_ slow because it has to remove things from the constraint objects. Do you mean `delete_constraints(m, val)`?

---

<div class="post-metadata">

### Author: ![Di11on](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/di11on/32/6352_2.png) [@Di11on](https://discourse.julialang.org/u/Di11on)
#### Post date: [March 21, 2019, 2:33pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/9 "2019-03-21T14:33:55Z")

</div>

Indeed!

---

<div class="post-metadata">

### Author: ![Di11on](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/di11on/32/6352_2.png) [@Di11on](https://discourse.julialang.org/u/Di11on)
#### Post date: [March 22, 2019, 10:11am UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/10 "2019-03-22T10:11:26Z")

</div>

Goodness… look at this:

```julia
using JuMP,CPLEX

const C = 300000
const N = 10

function test_const()
    m=Model(with_optimizer(CPLEX.Optimizer, CPX_PARAM_SCRIND=0))
    coef = rand(C,N)
    @variable(m, 0 <= x[1:N] <= 1)
    @variable(m, 0 <= Θ <= 1000)
    val, time, = @timed @constraint(m, Θ .<= coef*x )
    println("time to create constraints: ", time)
    val2, time = @timed delete_constraints(m,val)
    println("time to delete constraints: ", time)
end

function delete_constraints(m,x)
    delete.(m, x)
end

test_const()

```

Output:

```julia
time to create constraints: 4.891016396
time to delete constraints: 2522.593128827

```

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [March 22, 2019, 1:43pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/11 "2019-03-22T13:43:35Z")

</div>

The problem is that JuMP has to store a mapping between the constraint object (e.g., `val[10]`) and the row in the CPLEX constraint matrix (i.e., `10`). Thus, deleting constraints like this is n^2 in the number of constraints. When you delete a constraint, JuMP has to loop through all other constraints and update the mapping between the constraint and the row.

Deleting a few constraints is cheap. Deleting lots of constraints (e.g. `30_000`) is expensive. Do you really need to do this?

---

<div class="post-metadata">

### Author: ![Di11on](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/di11on/32/6352_2.png) [@Di11on](https://discourse.julialang.org/u/Di11on)
#### Post date: [March 22, 2019, 1:48pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/12 "2019-03-22T13:48:54Z")

</div>

As I was saying, I am solving in a loop and it would be nice if I could replace only those constraints that change… so the idea was to only the constraints that change and add a new version of them. But it looks like this is not the way to get the performance improvements I would like.

I am looking at **[ParameterJuMP.jl](https://github.com/JuliaStochOpt/ParameterJuMP.jl)** - this looks like it could do what we need.

Given that I want to add back the constraint, I wonder would something like constraint\_replace or constraint update make sense where you rebuild the constraint but don’t need to update the mapping? You also don’t need to worry about what’s the RHS etc. because you rebuild it from scratch.

---

<div class="post-metadata">

### Author: ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)
#### Post date: [March 22, 2019, 2:28pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/13 "2019-03-22T14:28:20Z")

</div>

Alternatively, you could use Parametron, which I built for these kinds of parameterized problems.

```julia
using Parametron, CPLEX
using Random

const C = 30000#300000
const N = 10

# Basic problem setup. Mostly the same as with JuMP, except
# the @constraint macro isn't quite as advanced.
const m = Model(CPLEX.Optimizer(CPX_PARAM_SCRIND=0))
x = [Variable(m) for i in 1 : N]
Θ = Variable(m)
@constraint m 0 <= Θ
@constraint m Θ <= 1000
for i in 1 : N
    @constraint m 0 <= x[i]
    @constraint m x[i] <= 1
end

# Now the interesting part: you can explicitly create a Parameter
# with an update function that will be called before each solve. Here
# create an update function that is a closure over a pre-allocated matrix
# using the standard `do` syntax.
const coef_val = zeros(C, N)
const coef = Parameter(coef_val, m) do coef_val
    rand!(coef_val)
end
@constraint m fill(Θ, C) <= coef * x

# Solve the first time
@time solve!(m) # currently produces some warnings...

# solving a second time will call the update function for the `coef`
# parameter and update the corresponding constraints in place.
@time solve!(m)

```

---

<div class="post-metadata">

### Author: ![Di11on](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/di11on/32/6352_2.png) [@Di11on](https://discourse.julialang.org/u/Di11on)
#### Post date: [March 22, 2019, 4:50pm UTC](https://discourse.julialang.org/t/deleting-containerized-constraints/21971/14 "2019-03-22T16:50:12Z")

</div>

Nice… this is exactly the kind of thing we’re looking at… thanks for the steer…

edit: never mind, I needed to scroll down!!
