Strange behavior with deepcopy

jump
#1

I’m getting a strange behavior with deepcopy. Deepcopy is still not supported? There is any way to copy JuMP model?

using JuMP, Clp

m = Model(solver = ClpSolver())
@variable(m, 0 <= x <= 2 )
@variable(m, 0 <= y <= 30 )
@objective(m, Max, 5x + 3*y )
@constraint(m, 1x + 5y <= 3.0 )
status = solve(m)
status ≠ :Optimal && erro(" status ≠ :Optimal $(status)")

m2 = deepcopy(m)
@constraint(m, 10*x + 15*y <= 3.0 ) # Add constraint to original problem
status = solve(m2)

And getting this error:

Array length must match number of rows in the model
chg_row_lower(::Clp.ClpCInterface.ClpModel, ::Array{Float64,1}) at ClpCInterface.jl:452
setconstrLB!(::Clp.ClpMathProgSolverInterface.ClpMathProgModel, ::Array{Float64,1}) at ClpSolverInterface.jl:131
#build#119(::Bool, ::Bool, ::JuMP.ProblemTraits, ::Function, ::JuMP.Model) at solvers.jl:337
(::JuMP.#kw##build)(::Array{Any,1}, ::JuMP.#build, ::JuMP.Model) at <missing>:0
#solve#116(::Bool, ::Bool, ::Bool, ::Array{Any,1}, ::Function, ::JuMP.Model) at solvers.jl:168
solve(::JuMP.Model) at solvers.jl:150
include_string(::String, ::String) at loading.jl:522
include_string(::String, ::String, ::Int64) at eval.jl:30
include_string(::Module, ::String, ::String, ::Int64, ::Vararg{Int64,N} where N) at eval.jl:34
(::Atom.##102#107{String,Int64,String})() at eval.jl:82
withpath(::Atom.##102#107{String,Int64,String}, ::Void) at utils.jl:30
withpath(::Function, ::String) at eval.jl:38
hideprompt(::Atom.##101#106{String,Int64,String}) at repl.jl:62
macro expansion at eval.jl:80 [inlined]
(::Atom.##100#105{Dict{String,Any}})() at task.jl:80

This doesn’t happen with copy(m).

#2

You can’t use deepcopy on a JuMP model. Mostly because after solve it has a Clp model in internamModel and that leads to all kinds of issues.

Basically what is happening here is that m2 stores a pointer to the Clp model, so calling solve(m2) is equivalent to calling solve(m), but m2 doesn’t have the additional RHS information from the constraint you added.

1 Like
#3

Ok. Thanks @odow!
There is any workaround? If I remove internamModel, for example?

Copy isn’t working for me either in JuMP 0.18.5, there is an issue with matrix constraints:

using JuMP
using CPLEX

m = Model(solver = CplexSolver())
@variable(m, 0 <= x <= 2 )
@variable(m, 0 <= y <= 30 )

@objective(m, Max, 5x + 3*y )
@constraint(m, 1x + 5y <= 3.0 )
@constraint(m, cons[i = 1:2, j=1:2], i*x + j*y <= 3.0 )
copy(m)
MethodError: no method matching copy(::Array{JuMP.ConstraintRef,2}, ::JuMP.Model)e[0m
Closest candidates are:
  copy(e[91m::JuMP.Variablee[39m, ::JuMP.Model) at /home/tas/.julia/v0.6/JuMP/src/JuMP.jl:502
  copy(e[91m::Voide[39m, ::JuMP.Model) at /home/tas/.julia/v0.6/JuMP/src/JuMP.jl:503
  copy(e[91m::JuMP.GenericAffExpr{Float64,JuMP.Variable}e[39m, ::JuMP.Model) at /home/tas/.julia/v0.6/JuMP/src/affexpr.jl:119
  ...
copy(::JuMP.Model) at JuMP.jl:300
include_string(::String, ::String) at loading.jl:522
include_string(::String, ::String, ::Int64) at eval.jl:30
include_string(::Module, ::String, ::String, ::Int64, ::Vararg{Int64,N} where N) at eval.jl:34
(::Atom.##102#107{String,Int64,String})() at eval.jl:82
withpath(::Atom.##102#107{String,Int64,String}, ::Void) at utils.jl:30
withpath(::Function, ::String) at eval.jl:38
hideprompt(::Atom.##101#106{String,Int64,String}) at repl.jl:62
macro expansion at eval.jl:80 [inlined]
(::Atom.##100#105{Dict{String,Any}})() at task.jl:80
#4

In JuMP 0.19.0 this code works.

#5

Great that it works in 0.19. Do you need to stay on 0.18.5?

#6

I will port sometime in the future, but not now. The issue with copying constraints is just because of the named constraints. I removed the names and seems that everything is working now.

#7

Just to finish this topic.
There are many people that use deepcopy with JuMP models and don’t know about this issue. Just two suggestions, I think this should be clear in JuMP documentation and using deepcopy in JuMP model should return an error.

1 Like