Model/variable copy error in JuMP 0.18

question

#1

I created a simple model and tried to copy and modify.

using JuMP, Clp

m = Model(solver=ClpSolver())
set_A = [(1,2), (2,3)]
@variable(m, x[(i,j) in set_A]>=0)
@objective(m, Max, sum(x[(i,j)] for (i,j) in set_A) )
@constraint(m, x[(1,2)]<=10)
@constraint(m, x[(2,3)]<=10)
solve(m)
@show getvalue(x)

m2 = copy(m)
x2 = copy(x, m2)
@constraint(m2, x2[(1,2)]<=1)
@constraint(m2, x2[(2,3)]<=1)
solve(m2)
@show getvalue(x2)

The last line creates an error. When tuples were not used in the variable definition, it works fine.

getvalue(x) = x: 1 dimensions:
[(1, 2)] = 10.0
[(2, 3)] = 10.0
ERROR: LoadError: 
Stacktrace:
 [1] getindex(::ObjectIdDict, ::JuMP.JuMPArray{JuMP.Variable,1,Tuple{Array{Tuple{Int64,Int64},1}}}) at ./associative.jl:363
 [2] _map(::Function, ::JuMP.JuMPArray{JuMP.Variable,1,Tuple{Array{Tuple{Int64,Int64},1}}}) at /Users/chkwon/.julia/v0.6/JuMP/src/JuMPContainer.jl:162
 [3] getvalue(::JuMP.JuMPArray{JuMP.Variable,1,Tuple{Array{Tuple{Int64,Int64},1}}}) at /Users/chkwon/.julia/v0.6/JuMP/src/JuMPContainer.jl:114
 [4] include_from_node1(::String) at ./loading.jl:576
 [5] include(::String) at ./sysimg.jl:14SYSTEM: show(lasterr) caused an error
AssertionError("j isa Array{Variable}")

Stacktrace:
 [1] getindex(::ObjectIdDict, ::JuMP.JuMPArray{JuMP.Variable,1,Tuple{Array{Tuple{Int64,Int64},1}}}) at ./associative.jl:363
 [2] _map(::Function, ::JuMP.JuMPArray{JuMP.Variable,1,Tuple{Array{Tuple{Int64,Int64},1}}}) at /Users/chkwon/.julia/v0.6/JuMP/src/JuMPContainer.jl:162
 [3] getvalue(::JuMP.JuMPArray{JuMP.Variable,1,Tuple{Array{Tuple{Int64,Int64},1}}}) at /Users/chkwon/.julia/v0.6/JuMP/src/JuMPContainer.jl:114
 [4] include_from_node1(::String) at ./loading.jl:576
 [5] include(::String) at ./sysimg.jl:14
 [6] eval(::Module, ::Any) at ./boot.jl:235
 [7] eval_user_input(::Any, ::Base.REPL.REPLBackend) at ./REPL.jl:66
 [8] macro expansion at ./REPL.jl:97 [inlined]
 [9] (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:73

Is this a bug?


#2

The error is from when it tries to print x2.

It probably shouldn’t error, but you can go x2 = m2[:x] instead of the copy.

It looks like @blegat last touched this stuff:



#3

copy(x, m2) is not meant to be called manually, it is already called in copy(m).


As you can see, inside copy(m), it also copies, the varData entries. If you call copy(x, m2) manually, you also need to do m2.varData[x2] = m.varData[x]


#4

Thanks @odow and @blegat.

Either

x2 = m2[:x]

or

x2 = copy(x, m2);
m2.varData[x2] = m.varData[x]

works. I think I should stick to the first one.