From 8edd031bbeda7f0378f624cca9147f8041d49b8b Mon Sep 17 00:00:00 2001 From: "Alinson S. Xavier" Date: Mon, 4 Aug 2025 21:00:36 -0500 Subject: [PATCH] FisSal2011: Add multiple variants --- src/Cuts/tableau/gmi_dual.jl | 88 +++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 27 deletions(-) diff --git a/src/Cuts/tableau/gmi_dual.jl b/src/Cuts/tableau/gmi_dual.jl index 4250ecf..71c964f 100644 --- a/src/Cuts/tableau/gmi_dual.jl +++ b/src/Cuts/tableau/gmi_dual.jl @@ -267,13 +267,32 @@ end function collect_gmi_FisSal2011( mps_filename; optimizer, - max_rounds = 10_000, max_cuts_per_round = 1_000_000, - time_limit = 900, - print_interval_sec=1, + time_limit = 3_600, + interval_print_sec=0.1, silent_solver=true, max_pool_size_mb = 1024, + variant = :fast, ) + variant in [:subg, :hybr, :fast, :faster] || error("unknown variant: $variant") + if variant == :subg + max_rounds = 10_000 + interval_large_lp = 10_000 + interval_read_tableau = 10 + elseif variant == :hybr + max_rounds = 10_000 + interval_large_lp = 1_000 + interval_read_tableau = 10 + elseif variant == :fast + max_rounds = 1_000 + interval_large_lp = 100 + interval_read_tableau = 1 + elseif variant == :faster + max_rounds = 500 + interval_large_lp = 50 + interval_read_tableau = 1 + end + reset_timer!() initial_time = time() @@ -307,7 +326,7 @@ function collect_gmi_FisSal2011( pool_cut_age = nothing pool_cut_hashes = Set{UInt64}() pool_size_mb = 0 - λ = 0 + λ, Δ = 0, 0 μ = 10 end @@ -350,6 +369,8 @@ function collect_gmi_FisSal2011( @info "Standard form model has $(length(data.var_lb)) vars, $(length(data.constr_lb)) constrs" for round = 1:max_rounds + should_print_log = false + if round > 1 @timeit "Update objective function" begin # Build Lagrangian term @@ -395,33 +416,41 @@ function collect_gmi_FisSal2011( error("Non-optimal termination status") end - Δ = obj_mip - obj_best - if obj_curr < obj_best - Δ - count_deterioration += 1 - else - count_deterioration = 0 - end - if count_deterioration >= 10 - μ *= 0.5 - multipliers_curr = multipliers_best - count_deterioration = 0 - count_backtrack += 1 - elseif length(obj_hist) >= 100 - obj_hist_avg = mean(obj_hist) - improv = obj_best - obj_hist[1] - if improv < 0.01 * Δ - if obj_best - obj_hist_avg < 0.001 * Δ - μ = 10 * μ - elseif obj_best - obj_hist_avg < 0.01 * Δ - μ = 2 * μ + @timeit "Update μ" begin + if variant in [:subg, :hybr] + Δ = obj_mip - obj_best + if obj_curr < obj_best - Δ + count_deterioration += 1 else - μ = 0.5 * μ + count_deterioration = 0 end + if count_deterioration >= 10 + μ *= 0.5 + multipliers_curr = multipliers_best + count_deterioration = 0 + count_backtrack += 1 + elseif length(obj_hist) >= 100 + obj_hist_avg = mean(obj_hist) + improv = obj_best - obj_hist[1] + if improv < 0.01 * Δ + if obj_best - obj_hist_avg < 0.001 * Δ + μ = 10 * μ + elseif obj_best - obj_hist_avg < 0.01 * Δ + μ = 2 * μ + else + μ = 0.5 * μ + end + end + end + elseif variant in [:fast, :faster] + μ = 0.01 + else + error("not implemented") end end end - if mod(round, 10) == 1 + if mod(round - 1, interval_read_tableau) == 0 @timeit "Select tableau rows" begin basis = get_basis(model_s) basis_hash = hash(basis) @@ -481,7 +510,8 @@ function collect_gmi_FisSal2011( end end - if mod(round, 1000) == 1 || round == max_rounds + if mod(round - 1, interval_large_lp) == 0 || round == max_rounds + should_print_log = true @timeit "Update multipliers (large LP)" begin selected_idx = [] selected_contrs = [] @@ -601,7 +631,11 @@ function collect_gmi_FisSal2011( ) end - if time() - last_print_time > print_interval_sec + if time() - last_print_time > interval_print_sec + should_print_log = true + end + + if should_print_log last_print_time = time() @printf( "%8d %10.3e %9.2e %9.2e %9d %9.2f %9d %4d %8.2e %8.2e %8.2e\n",