Adding new constraints

Dear all,
I have a MWE where I want to add new constraints into a model inside a function:

m,n=10,20
A=rand(-10:10,m,n)
b=[sum(A[i,:]) for i in 1:m]/2

function Basic_model(A,b,n)
    modelo = Model(Gurobi.Optimizer)
    @variable(modelo, x[1:n] >=0, Bin)
    @objective(modelo, Min, sum(x[i] for i in 1:n))
    @constraint(modelo,[i in 1:m],
    A*x .>= b
    )
    @constraint(modelo, con, x[3] + x[2] == 1)
    return (modelo)
end
modelo = Basic_model(A,b,n)
@constraint(modelo, x[1] + x[5] ==1)
optimize!(modelo)

The function Basic_model only build the model to optimize in the future. I want to add new constraints, like this:

@constraint(modelo, x[1] + x[5] ==1)

but this does not work.
Could be possible I build the main model and add/remove new constraints iteratively, outside the function? What is the wrong in the above code?
For some reason, I need to add/remove constraints after the construction of the main model.
O don’t want to rebuild my model several times (because the insertion/remotion of constraints) from initial stage to save computational effort.
Thanks.

1 Like

Your error is:

julia> using JuMP, Gurobi

julia> function Basic_model(A, b, n)
           modelo = Model(Gurobi.Optimizer)
           @variable(modelo, x[1:n] >= 0, Bin)
           @objective(modelo, Min, sum(x[i] for i in 1:n))
           @constraint(modelo,[i in 1:m], A * x .>= b)
           @constraint(modelo, con, x[3] + x[2] == 1)
           return modelo
       end
Basic_model (generic function with 1 method)

julia> m, n = 10, 20
(10, 20)

julia> A = rand(-10:10, m, n);

julia> b = [sum(A[i, :]) for i in 1:m] / 2;

julia> modelo = Basic_model(A, b, n);

julia> @constraint(modelo, x[1] + x[5] == 1)
ERROR: UndefVarError: `x` not defined
Stacktrace:
 [1] macro expansion
   @ ~/.julia/packages/MutableArithmetics/iovKe/src/rewrite.jl:325 [inlined]
 [2] macro expansion
   @ ~/.julia/packages/JuMP/Gwn88/src/macros.jl:257 [inlined]
 [3] macro expansion
   @ ~/.julia/packages/JuMP/Gwn88/src/macros/@constraint.jl:131 [inlined]
 [4] macro expansion
   @ ~/.julia/packages/JuMP/Gwn88/src/macros.jl:393 [inlined]
 [5] top-level scope
   @ REPL[7]:1

This is because x is defined inside the function, and it is not accessible outside.

To fix, you either need to do:

julia> x = modelo[:x]
20-element Vector{VariableRef}:
 x[1]
 x[2]
 x[3]
 x[4]
 x[5]
 x[6]
 x[7]
 x[8]
 x[9]
 x[10]
 x[11]
 x[12]
 x[13]
 x[14]
 x[15]
 x[16]
 x[17]
 x[18]
 x[19]
 x[20]

julia> @constraint(modelo, x[1] + x[5] == 1)
x[1] + x[5] = 1

Or you need to return x from the function:

using JuMP, Gurobi
function Basic_model(A, b, n)
    modelo = Model(Gurobi.Optimizer)
    @variable(modelo, x[1:n] >= 0, Bin)
    @objective(modelo, Min, sum(x[i] for i in 1:n))
    @constraint(modelo,[i in 1:m], A * x .>= b)
    @constraint(modelo, con, x[3] + x[2] == 1)
    return modelo, x
end
modelo, x = Basic_model(A, b, n);

It may help if you read Design patterns for larger models · JuMP