# Efficient deletion of affine constraints

**URL:** https://discourse.julialang.org/t/efficient-deletion-of-affine-constraints/67529
**Category:** Optimization (Mathematical)
**Tags:** question, jump
**Created:** [September 1, 2021, 8:01pm UTC](https://discourse.julialang.org/t/efficient-deletion-of-affine-constraints/67529 "2021-09-01T20:01:28Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![bsturt](https://avatars.discourse-cdn.com/v4/letter/b/bbe5ce/32.png) [@bsturt](https://discourse.julialang.org/u/bsturt)
#### Post date: [September 1, 2021, 8:01pm UTC](https://discourse.julialang.org/t/efficient-deletion-of-affine-constraints/67529/1 "2021-09-01T20:01:28Z")

</div>

Many apologies in advance if this topic has already been answered.

I am implementing an cutting plane algorithm for solving a class of large-scale LPs using JuMP and Gurobi. Because the model requires lots of RAM, I am trying to efficiently delete the (possibly large number of) non-binding constraints in each iteration of my algorithm. I am looking for guidance on the most efficient way to delete constraints.

Specifically, in the MWE below, I generate a linear program with a large number of constraints. After solving the LP, the code uses the `delete` function to remove the non-active constraints. (In my real code, I then add new constraints and resolve the problem.)

```julia
using JuMP
using Gurobi

println("Define random problem instance")
@time begin
    m = 1000
    n = 10
    A = rand(m,n)
    b = ones(m)
end

println("Define restricted optimization problem over active set")
@time begin
    # For simplicity, suppose we have added all of the constraints.
    active_set = Set()
    for i=1:m
        push!(active_set, i)
    end

    model = Model(Gurobi.Optimizer)
    set_silent(model)
    @variable(model, x[1:n] >= 0)
    @constraint(model, cons[i=1:m; i in active_set], dot(A[i,:], x) ≥ b[i])
    @objective(model, Min, sum(x[j] for j=1:n))
end

println("Solve restricted optimization problem")
@time optimize!(model)

println("Prepare to delete the non-active constraints")
@time begin
    x_opt = value.(x)
    to_remove = Vector{ConstraintRef}()
    for i in active_set
        if dot(A[i,:],x_opt) > b[i]
            push!(to_remove, cons[i])
        end
    end
end

println("Delete the non-active constraints")
@time delete(model, to_remove)

println("Resolve the optimization problem")
@time optimize!(model)

```

The output of the above code is the following:

```julia
Define random problem instance
  0.000918 seconds (4 allocations: 1.679 MiB)
Define restricted optimization problem over active set
Academic license - for non-commercial use only
  0.598139 seconds (2.06 M allocations: 99.967 MiB, 29.81% gc time)
Solve restricted optimization problem
  0.090948 seconds (140.88 k allocations: 20.427 MiB)
Prepare to delete the non-active constraints
  0.018719 seconds (238.28 k allocations: 7.799 MiB)
Delete the non-active constraints
  7.000508 seconds (237.78 k allocations: 6.809 MiB)
Resolve the optimization problem
  0.000383 seconds (36 allocations: 1.094 KiB)

```

Clearly, the deletion step is the bottleneck in the code. I have done some searching through past pull requests and issues for JuMP related to deleting constraints (such as [https://github.com/jump-dev/Gurobi.jl/pull/313](https://github.com/jump-dev/Gurobi.jl/pull/313) and the discussion [here](https://discourse.julialang.org/t/jump-0-21-how-to-efficiently-delete-non-binding-constraints-in-an-lp/40650)). However, I have not seemed to find a solution to this performance issue.

Is there any straightforward way to improve the performance of the above code? Specifically, are there any performance tips on efficiently deleting constraints in a JuMP model with the Gurobi solver? If not, is this possible with any other solvers? Any advice or guidance would be greatly appreciated!

---

<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: [September 1, 2021, 8:47pm UTC](https://discourse.julialang.org/t/efficient-deletion-of-affine-constraints/67529/2 "2021-09-01T20:47:28Z")

</div>

Try this with

```nohighlight
model = direct_model(Gurobi.Optimizer())

```

Gurobi has some very peculiar semantics around how it updates the model after a deletion, so it can be hard to make it efficient in all cases.

---

<div class="post-metadata">

### Author: ![bsturt](https://avatars.discourse-cdn.com/v4/letter/b/bbe5ce/32.png) [@bsturt](https://discourse.julialang.org/u/bsturt)
#### Post date: [September 1, 2021, 8:55pm UTC](https://discourse.julialang.org/t/efficient-deletion-of-affine-constraints/67529/3 "2021-09-01T20:55:47Z")

</div>

Works perfectly! Many thanks!

---

<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: [September 1, 2021, 8:56pm UTC](https://discourse.julialang.org/t/efficient-deletion-of-affine-constraints/67529/4 "2021-09-01T20:56:53Z")

</div>

Great! It’s on our radar to fix the first case. But it requires some extra plumbing in various places.
