|
|
|
@ -335,6 +335,13 @@ function collect_gmi_FisSal2011(
|
|
|
|
|
basis_cache = nothing
|
|
|
|
|
λ, Δ = 0, 0
|
|
|
|
|
μ = 10
|
|
|
|
|
|
|
|
|
|
basis_vars_to_id = Dict()
|
|
|
|
|
basis_id_to_vars = Dict{Int, Vector{Int}}()
|
|
|
|
|
basis_id_to_sizes = Dict{Int, Vector{Int}}()
|
|
|
|
|
next_basis_id = 1
|
|
|
|
|
cut_basis_id = Int[]
|
|
|
|
|
cut_row = Int[]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
gapcl(v) = 100 * (v - obj_initial) / (obj_mip - obj_initial)
|
|
|
|
@ -513,6 +520,25 @@ function collect_gmi_FisSal2011(
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
@timeit "Append unique cuts" begin
|
|
|
|
|
@timeit "Track basis" begin
|
|
|
|
|
vb = basis.var_basic
|
|
|
|
|
vn = basis.var_nonbasic
|
|
|
|
|
cb = basis.constr_basic
|
|
|
|
|
cn = basis.constr_nonbasic
|
|
|
|
|
basis_vars = [vb; vn; cb; cn]
|
|
|
|
|
basis_sizes = [length(vb), length(vn), length(cb), length(cn)]
|
|
|
|
|
|
|
|
|
|
if basis_vars ∉ keys(basis_vars_to_id)
|
|
|
|
|
basis_id = next_basis_id
|
|
|
|
|
basis_vars_to_id[basis_vars] = basis_id
|
|
|
|
|
basis_id_to_vars[basis_id] = basis_vars
|
|
|
|
|
basis_id_to_sizes[basis_id] = basis_sizes
|
|
|
|
|
next_basis_id += 1
|
|
|
|
|
else
|
|
|
|
|
basis_id = basis_vars_to_id[basis_vars]
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if round == 1
|
|
|
|
|
pool = ConstraintSet(
|
|
|
|
|
lhs = sparse(cuts_s.lhs[unique_indices, :]'),
|
|
|
|
@ -524,6 +550,10 @@ function collect_gmi_FisSal2011(
|
|
|
|
|
multipliers_curr = zeros(ncuts_unique)
|
|
|
|
|
multipliers_best = zeros(ncuts_unique)
|
|
|
|
|
pool_cut_age = zeros(ncuts_unique)
|
|
|
|
|
for i in unique_indices
|
|
|
|
|
push!(cut_basis_id, basis_id)
|
|
|
|
|
push!(cut_row, selected_rows[i])
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
if !isempty(unique_indices)
|
|
|
|
|
@timeit "Append LHS" begin
|
|
|
|
@ -557,6 +587,10 @@ function collect_gmi_FisSal2011(
|
|
|
|
|
append!(multipliers_curr, zeros(ncuts_unique))
|
|
|
|
|
append!(multipliers_best, zeros(ncuts_unique))
|
|
|
|
|
append!(pool_cut_age, zeros(ncuts_unique))
|
|
|
|
|
for i in unique_indices
|
|
|
|
|
push!(cut_basis_id, basis_id)
|
|
|
|
|
push!(cut_row, selected_rows[i])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
@ -588,6 +622,19 @@ function collect_gmi_FisSal2011(
|
|
|
|
|
multipliers_curr = multipliers_curr[idx_keep]
|
|
|
|
|
multipliers_best = multipliers_best[idx_keep]
|
|
|
|
|
pool_cut_age = pool_cut_age[idx_keep]
|
|
|
|
|
cut_basis_id = cut_basis_id[idx_keep]
|
|
|
|
|
cut_row = cut_row[idx_keep]
|
|
|
|
|
end
|
|
|
|
|
@timeit "Update known bases" begin
|
|
|
|
|
used_basis_ids = Set(cut_basis_id)
|
|
|
|
|
for basis_id in collect(keys(basis_id_to_vars))
|
|
|
|
|
if basis_id ∉ used_basis_ids
|
|
|
|
|
basis_vars = basis_id_to_vars[basis_id]
|
|
|
|
|
delete!(basis_vars_to_id, basis_vars)
|
|
|
|
|
delete!(basis_id_to_vars, basis_id)
|
|
|
|
|
delete!(basis_id_to_sizes, basis_id)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
pool_size_mb = Base.summarysize(pool) / 1024^2
|
|
|
|
|
end
|
|
|
|
@ -747,13 +794,62 @@ function collect_gmi_FisSal2011(
|
|
|
|
|
|
|
|
|
|
@timeit "Keep only active cuts" begin
|
|
|
|
|
positive_idx = findall(multipliers_best .> 1e-6)
|
|
|
|
|
@info "Keeping $(length(positive_idx)) active cuts"
|
|
|
|
|
pool.lhs = pool.lhs[:, positive_idx]
|
|
|
|
|
pool.lb = pool.lb[positive_idx]
|
|
|
|
|
pool.ub = pool.ub[positive_idx]
|
|
|
|
|
pool.hash = pool.hash[positive_idx]
|
|
|
|
|
multipliers_best = multipliers_best[positive_idx]
|
|
|
|
|
multipliers_curr = multipliers_curr[positive_idx]
|
|
|
|
|
|
|
|
|
|
@timeit "Clean up cut pool" begin
|
|
|
|
|
pool.lhs = pool.lhs[:, positive_idx]
|
|
|
|
|
pool.lb = pool.lb[positive_idx]
|
|
|
|
|
pool.ub = pool.ub[positive_idx]
|
|
|
|
|
pool.hash = pool.hash[positive_idx]
|
|
|
|
|
multipliers_best = multipliers_best[positive_idx]
|
|
|
|
|
multipliers_curr = multipliers_curr[positive_idx]
|
|
|
|
|
cut_basis_id = cut_basis_id[positive_idx]
|
|
|
|
|
cut_row = cut_row[positive_idx]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@timeit "Clean up known bases" begin
|
|
|
|
|
used_basis_ids = Set(cut_basis_id)
|
|
|
|
|
for basis_id in collect(keys(basis_id_to_vars))
|
|
|
|
|
if basis_id ∉ used_basis_ids
|
|
|
|
|
basis_vars = basis_id_to_vars[basis_id]
|
|
|
|
|
delete!(basis_vars_to_id, basis_vars)
|
|
|
|
|
delete!(basis_id_to_vars, basis_id)
|
|
|
|
|
delete!(basis_id_to_sizes, basis_id)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@info "Keeping $(length(positive_idx)) cuts from $(length(used_basis_ids)) unique bases"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@timeit "Write cuts to H5" begin
|
|
|
|
|
if !isempty(cut_basis_id)
|
|
|
|
|
@timeit "Convert IDs to offsets" begin
|
|
|
|
|
id_to_offset = Dict{Int, Int}()
|
|
|
|
|
gmi_basis_vars = []
|
|
|
|
|
gmi_basis_sizes = []
|
|
|
|
|
for (offset, basis_id) in enumerate(sort(collect(keys(basis_id_to_vars))))
|
|
|
|
|
id_to_offset[basis_id] = offset
|
|
|
|
|
push!(gmi_basis_vars, basis_id_to_vars[basis_id])
|
|
|
|
|
push!(gmi_basis_sizes, basis_id_to_sizes[basis_id])
|
|
|
|
|
end
|
|
|
|
|
gmi_cut_basis = [id_to_offset[basis_id] for basis_id in cut_basis_id]
|
|
|
|
|
gmi_cut_row = cut_row
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@timeit "Convert to matrices" begin
|
|
|
|
|
gmi_basis_vars_matrix = hcat(gmi_basis_vars...)'
|
|
|
|
|
gmi_basis_sizes_matrix = hcat(gmi_basis_sizes...)'
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@timeit "Write H5" begin
|
|
|
|
|
h5 = H5File(h5_filename, "r+")
|
|
|
|
|
h5.put_array("gmi_basis_vars", gmi_basis_vars_matrix)
|
|
|
|
|
h5.put_array("gmi_basis_sizes", gmi_basis_sizes_matrix)
|
|
|
|
|
h5.put_array("gmi_cut_basis", gmi_cut_basis)
|
|
|
|
|
h5.put_array("gmi_cut_row", gmi_cut_row)
|
|
|
|
|
h5.file.close()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
to = TimerOutputs.get_defaulttimer()
|
|
|
|
|