From 5bcbed5bccfc25309458a26ad050189c6497f972 Mon Sep 17 00:00:00 2001 From: NatachaJaverzat <95150195+enjoyUrFruits@users.noreply.github.com> Date: Thu, 4 May 2023 16:56:19 +0200 Subject: [PATCH] enforce convergence condition (#861) * enforce convergence condition * update tests --------- Co-authored-by: Guillaume Marques --- src/Algorithm/colgen/default.jl | 18 +++++++++++++----- src/ColGen/interface.jl | 4 ++-- test/unit/ColGen/colgen_phase.jl | 3 ++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Algorithm/colgen/default.jl b/src/Algorithm/colgen/default.jl index a5f759277..80b787685 100644 --- a/src/Algorithm/colgen/default.jl +++ b/src/Algorithm/colgen/default.jl @@ -62,6 +62,7 @@ struct ColGenPhaseOutput <: ColGen.AbstractColGenPhaseOutput exact_stage::Bool time_limit_reached::Bool nb_iterations::Int + min_sense::Bool end struct ColGenOutput <: ColGen.AbstractColGenOutput @@ -143,7 +144,12 @@ end colgen_master_has_new_cuts(output::ColGenPhaseOutput) = output.new_cut_in_master colgen_uses_exact_stage(output::ColGenPhaseOutput) = output.exact_stage -colgen_has_converged(output::ColGenPhaseOutput) = !isnothing(output.mlp) && !isnothing(output.db) && abs(output.mlp - output.db) < 1e-5 +colgen_has_converged(output::ColGenPhaseOutput) = !isnothing(output.mlp) && + !isnothing(output.db) && ( + ( abs(output.mlp - output.db) < 1e-5 ) || + ( (output.min_sense) && (output.db >= output.mlp) ) || + ( !(output.min_sense) && (output.db <= output.mlp) ) + ) colgen_has_no_new_cols(output::ColGenPhaseOutput) = output.no_more_columns ## Implementation of `next_phase`. @@ -684,7 +690,7 @@ ColGen.after_colgen_iteration(ctx::ColGenContext, phase, stage, env, colgen_iter ColGen.colgen_phase_output_type(::ColGenContext) = ColGenPhaseOutput -function ColGen.new_phase_output(::Type{<:ColGenPhaseOutput}, phase, stage, colgen_iter_output::ColGenIterationOutput, iteration) +function ColGen.new_phase_output(::Type{<:ColGenPhaseOutput}, min_sense, phase, stage, colgen_iter_output::ColGenIterationOutput, iteration) return ColGenPhaseOutput( colgen_iter_output.master_lp_primal_sol, colgen_iter_output.master_ip_primal_sol, @@ -696,11 +702,12 @@ function ColGen.new_phase_output(::Type{<:ColGenPhaseOutput}, phase, stage, colg colgen_iter_output.infeasible_master || colgen_iter_output.infeasible_subproblem, ColGen.is_exact_stage(stage), colgen_iter_output.time_limit_reached, - iteration + iteration, + min_sense ) end -function ColGen.new_phase_output(::Type{<:ColGenPhaseOutput}, phase::ColGenPhase1, stage, colgen_iter_output::ColGenIterationOutput, iteration) +function ColGen.new_phase_output(::Type{<:ColGenPhaseOutput}, min_sense, phase::ColGenPhase1, stage, colgen_iter_output::ColGenIterationOutput, iteration) return ColGenPhaseOutput( colgen_iter_output.master_lp_primal_sol, colgen_iter_output.master_ip_primal_sol, @@ -712,7 +719,8 @@ function ColGen.new_phase_output(::Type{<:ColGenPhaseOutput}, phase::ColGenPhase colgen_iter_output.infeasible_master || colgen_iter_output.infeasible_subproblem || abs(colgen_iter_output.mlp) > 1e-5, ColGen.is_exact_stage(stage), colgen_iter_output.time_limit_reached, - iteration + iteration, + min_sense ) end diff --git a/src/ColGen/interface.jl b/src/ColGen/interface.jl index 4b87ee07b..79b85ced1 100644 --- a/src/ColGen/interface.jl +++ b/src/ColGen/interface.jl @@ -61,7 +61,7 @@ function run_colgen_phase!(context, phase, stage, env, ip_primal_sol; iter = 1) iteration += 1 end O = colgen_phase_output_type(context) - return new_phase_output(O, phase, stage, colgen_iter_output, iteration) + return new_phase_output(O, is_minimization(context), phase, stage, colgen_iter_output, iteration) end function run!(context, env, ip_primal_sol; iter = 1) @@ -237,7 +237,7 @@ abstract type AbstractColGenIterationOutput end @mustimplement "ColGenIterationOutput" get_master_ip_primal_sol(::AbstractColGenIterationOutput) = nothing -@mustimplement "ColGenPhaseOutput" new_phase_output(::Type{<:AbstractColGenPhaseOutput}, phase, stage, ::AbstractColGenIterationOutput, iteration) = nothing +@mustimplement "ColGenPhaseOutput" new_phase_output(::Type{<:AbstractColGenPhaseOutput}, min_sense, phase, stage, ::AbstractColGenIterationOutput, iteration) = nothing @mustimplement "ColGenPhaseOutput" get_master_ip_primal_sol(::AbstractColGenPhaseOutput) = nothing diff --git a/test/unit/ColGen/colgen_phase.jl b/test/unit/ColGen/colgen_phase.jl index 1cb7cd96b..4662a0bdb 100644 --- a/test/unit/ColGen/colgen_phase.jl +++ b/test/unit/ColGen/colgen_phase.jl @@ -494,7 +494,8 @@ function infeasible_phase_output() true, #infeasible true, #exact_stage false, - 6 + 6, + true ) @test ColGen.stop_colgen(ctx, colgen_phase_output)