I am working on an optimization problem where I have to group a permutation of jobs, which have some characteristics. A solution to this problem can be easily represented as a vector of vectors of a type Batch, where Batch is a mutable struct defined as follows:
I have also a reference solution called sol_ref which is also a vector of vectors of type batch and size m. The inner vectors are allowed to have a different size.
During the execution of my program I often have to replace sol with sol_ref and vice-versa. However, I want to avoid using deepcopy(), since it is memory intensive. My idea was to delete all elements manually and then replace the inner elements of each vector iteratively:
function Replace_Solution(sol::Vector{Vector{Batch}}, sol_ref::Vector{Vector{Batch}}, m::Int8)
#----- Replaces the current solution with new ones
for i in 1:m
empty!(sol[i])
append!(sol[i], sol_ref[i])
end
end
However, Replace_Solution often leads to errors since it is not guaranteeing separate memory allocations. I am looking for ways to efficiently update sol with the contents of sol_ref. Can anyone give my a perspective of why this is happening?
OBS: When I use deepcopy(), the algorithm runs fine.
The issue is that the the mutable structures will copied (when using append!) by reference, such that they will reference the same structures (note that even if the structure was not mutable, having the mutable Jobs field in it would cause you issues of the same sort). Thus, you need to copy the values explicitly for all elements of the structure One way to do it is to define a function to copy the data between two instances of Batch, and then use that. For example, something like:
julia> function copy_data!(target::Batch, source::Batch)
target.Size = source.Size
target.Family = source.Family
target.Jobs .= source.Jobs
return target
end
copy_data! (generic function with 1 method)
to be used with:
julia> function Replace_Solution!(sol::Vector{Vector{Batch}}, sol_ref::Vector{Vector{Batch}}, m)
for i in eachindex(sol,sol_ref)
copy_data!(sol[i], sol_ref[i])
end
return sol
end
Replace_Solution (generic function with 1 method)
help?> copy!
search: copy! copyto! circcopy! unsafe_copyto! replaceproperty! copy copysign
copy!(dst, src) -> dst
In-place copy of src into dst, discarding any pre-existing elements in dst.
If dst and src are of the same type, dst == src should hold after the call.
If dst and src are multidimensional arrays, they must have equal axes.
See also copyto!.
│ Julia 1.1
│
│ This method requires at least Julia 1.1. In Julia 1.0 this method
│ is available from the Future standard library as Future.copy!.