diff --git a/src/Cuts/tableau/gmi.jl b/src/Cuts/tableau/gmi.jl index 600b912..86a17db 100644 --- a/src/Cuts/tableau/gmi.jl +++ b/src/Cuts/tableau/gmi.jl @@ -296,7 +296,7 @@ function compute_gmi(data::ProblemData, tableau::Tableau)::ConstraintSet end end end - + @timeit "Resize arrays to actual size" begin resize!(lhs_I, nnz_count) resize!(lhs_J, nnz_count) diff --git a/src/Cuts/tableau/gmi_dual.jl b/src/Cuts/tableau/gmi_dual.jl index f897700..ec7a55d 100644 --- a/src/Cuts/tableau/gmi_dual.jl +++ b/src/Cuts/tableau/gmi_dual.jl @@ -271,7 +271,7 @@ function collect_gmi_FisSal2011( max_pool_size_mb = 1024, optimizer, silent_solver=true, - time_limit = 900, + time_limit = 3_600, variant = :fast, ) variant in [:subg, :hybr, :fast, :faster] || error("unknown variant: $variant") @@ -638,7 +638,8 @@ function collect_gmi_FisSal2011( if round == 1 @printf( - " %8s %10s %9s %9s %9s %9s %4s %8s %8s %8s\n", + " %8s %8s %10s %9s %9s %9s %9s %4s %8s %8s %8s\n", + "time", "round", "obj", "cl_curr", @@ -659,8 +660,9 @@ function collect_gmi_FisSal2011( if log_should_print last_print_time = time() @printf( - "%c %8d %10.3e %9.2e %9.2e %9d %9.2f %4d %8.2e %8.2e %8.2e\n", + "%c %8.2f %8d %10.3e %9.2e %9.2e %9d %9.2f %4d %8.2e %8.2e %8.2e\n", log_prefix, + time() - initial_time, round, obj_curr, gapcl_curr, diff --git a/src/Cuts/tableau/tableau.jl b/src/Cuts/tableau/tableau.jl index b6bbfc0..961dc2c 100644 --- a/src/Cuts/tableau/tableau.jl +++ b/src/Cuts/tableau/tableau.jl @@ -73,47 +73,65 @@ function compute_tableau( factor = klu(sparse(lhs_b')) end - @timeit "Compute tableau" begin - @timeit "Initialize sparse arrays" begin - tableau_rhs = zeros(length(rows)) - tableau_lhs_I = Int[] - tableau_lhs_J = Int[] - tableau_lhs_V = Float64[] - - # Heuristic: 5% sparsity - estimated_nnz = max(div(length(rows) * ncols, 20), length(rows)) - sizehint!(tableau_lhs_I, estimated_nnz) - sizehint!(tableau_lhs_J, estimated_nnz) - sizehint!(tableau_lhs_V, estimated_nnz) + @timeit "Initialize sparse arrays" begin + tableau_rhs::Array{Float64} = zeros(length(rows)) + tableau_lhs_I::Array{Int} = Int[] + tableau_lhs_J::Array{Int} = Int[] + tableau_lhs_V::Array{Float64} = Float64[] + estimated_nnz::Int = length(rows) * ncols รท 20 + sizehint!(tableau_lhs_I, estimated_nnz) + sizehint!(tableau_lhs_J, estimated_nnz) + sizehint!(tableau_lhs_V, estimated_nnz) + e::Array{Float64} = zeros(nrows) + sol::Array{Float64} = zeros(nrows) + tableau_row::Array{Float64} = zeros(ncols) + end + + A = data.constr_lhs' + b = data.constr_ub + + for k in eachindex(rows) + @timeit "Solve" begin + fill!(e, 0.0) + e[rows[k]] = 1.0 + ldiv!(sol, factor, e) end - - for k in eachindex(rows) - @timeit "Prepare inputs" begin - i = rows[k] - e = zeros(nrows) - e[i] = 1.0 - end - @timeit "Solve" begin - sol = factor \ e - end - @timeit "Compute row" begin - tableau_row = sol' * data.constr_lhs - tableau_rhs[k] = sol' * data.constr_ub + + @timeit "Compute row" begin + mul!(tableau_row, A, sol) + tableau_rhs[k] = dot(sol, b) + end + + needed_space = length(tableau_lhs_I) + ncols + if needed_space > estimated_nnz + @timeit "Grow arrays" begin + estimated_nnz *= 2 + sizehint!(tableau_lhs_I, estimated_nnz) + sizehint!(tableau_lhs_J, estimated_nnz) + sizehint!(tableau_lhs_V, estimated_nnz) end - @timeit "Collect nonzeros" begin - for j in 1:ncols - val = tableau_row[j] - if abs(val) > tol - push!(tableau_lhs_I, k) - push!(tableau_lhs_J, j) - push!(tableau_lhs_V, val) - end + end + + @timeit "Collect nonzeros" begin + for j in 1:ncols + val = tableau_row[j] + if abs(val) > tol + push!(tableau_lhs_I, k) + push!(tableau_lhs_J, j) + push!(tableau_lhs_V, val) end end end - @timeit "Build sparse matrix" begin - tableau_lhs = sparse(tableau_lhs_I, tableau_lhs_J, tableau_lhs_V, length(rows), ncols) - end + end + + @timeit "Shrink arrays" begin + sizehint!(tableau_lhs_I, 0) + sizehint!(tableau_lhs_J, 0) + sizehint!(tableau_lhs_V, 0) + end + + @timeit "Build sparse matrix" begin + tableau_lhs = sparse(tableau_lhs_I, tableau_lhs_J, tableau_lhs_V, length(rows), ncols) end @timeit "Compute tableau objective row" begin