Why after copying a JuMP model it does not own the initial model variables?

I am working on a MIP problem including two variables y[1] and y[2].

• y[1] is a binary

• y[2] is a positive real number

First I relax the binary restriction by 0 <=y[1] and -y[1] >= -1 and solve the relaxation.

``````c1 = [-2 ; 4]
A1 = [-3 1 ; -1 0 ]
b1 = [-2 ; -1]
sub = Model(GLPK.Optimizer)
@variable(sub, 0 ≤ y[1:2] )
@objective(sub, Min, c1' * y )
@constraint(sub, A1 * y .≥ b1)
optimize!(sub)
yᵏ = value.(y)
yᵏ = round.(yᵏ , digits = 2)
print(sub)
@show yᵏ;
``````

The output of above code is:

``````yᵏ = [0.67, 0.0]
``````

Now since y[1] = 0.67 is fractional I want to define two new linear models and call them sub_0 and sub_1.

Everything in sub_0 is same as sub except it has the extra constraint -y[0] >= 0.
Everything in sub_1 is same as sub except it has the extra constraint y[1] >= 1.

I script the below code for developing sub_0

``````sub_0 = copy(sub)
@show all_variables(sub_0)
c2 = @constraint(sub_0, - y[1] ≥ 0 )
``````

and see this error:

``````all_variables(sub_0) = VariableRef[y[1], y[2]]
VariableNotOwned{VariableRef}(y[1])

Stacktrace:
[1] check_belongs_to_model
@ C:\Users\e29115\.julia\packages\JuMP\klrjG\src\variables.jl:208 [inlined]
[2] check_belongs_to_model(a::AffExpr, model::Model)
@ JuMP C:\Users\e29115\.julia\packages\JuMP\klrjG\src\aff_expr.jl:499
[3] check_belongs_to_model
@ C:\Users\e29115\.julia\packages\JuMP\klrjG\src\constraints.jl:453 [inlined]
@ JuMP C:\Users\e29115\.julia\packages\JuMP\klrjG\src\constraints.jl:557
[5] top-level scope
@ In[29]:3
[6] eval
@ .\boot.jl:360 [inlined]
[7] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
``````

This minimal error-reproducing example

``````c1 = [-2 ; 4]
A1 = [-3 1 ; -1 0 ]
b1 = [-2 ; -1]
sub = Model()
@variable(sub, 0 ≤ y[1:2] )
@objective(sub, Min, c1' * y )
@constraint(sub, A1 * y .≥ b1)
sub_0 = copy(sub)
c2 = @constraint(sub_0, - y[1] ≥ 0 )
``````

does not depend on solving the model, but on the fact that you are copying the model then trying to use the variable `y[1]`, which belongs to the Model `sub`, with the Model `sub_0`.
I suppose your question is, how do you create a model copy that owns its own copy of the variable?

1 Like

So, you need to make the Julia variable `y` correspond to the JuMP variable `y` in Model `sub_0`:

``````y = sub_0[:y]
``````

then you can use it to modify `sub_0` using

``````c2 = @constraint(sub_0, - y[1] ≥ 0 )
``````
1 Like

You can also use `copy_model` instead of `copy` to get a map that converts original models into their copied equivalents: Models · JuMP

``````c1 = [-2 ; 4]
A1 = [-3 1 ; -1 0 ]
b1 = [-2 ; -1]
sub = Model()
@variable(sub, 0 ≤ y[1:2] )
@objective(sub, Min, c1' * y )
@constraint(sub, A1 * y .≥ b1)
sub_0, index_map = copy_model(sub)
c2 = @constraint(sub_0, - index_map[y[1]] ≥ 0 )
``````