Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect subproblem infeasibility #364

Merged
merged 2 commits into from
Jun 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/Algorithm/colgen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ function solve_sp_to_gencol!(
if !isfeasible(sp_optstate)
sp_is_feasible = false
# @logmsg LogLevel(-3) "pricing prob is infeasible"
return sp_is_feasible, recorded_solution_ids, PrimalBound(spform)
return sp_is_feasible, recorded_solution_ids, sp_solution_ids_to_activate, PrimalBound(spform)
end

if nb_ip_primal_sols(sp_optstate) > 0
Expand Down Expand Up @@ -361,6 +361,7 @@ function solve_sps_to_gencols!(
recorded_sp_solution_ids = Dict{FormId, Vector{VarId}}()
sp_solution_to_activate = Dict{FormId, Vector{VarId}}()
sp_dual_bound_contribs = Dict{FormId, Float64}()
gen_statuses = Dict{FormId, Bool}()

# update reduced costs
updatereducedcosts!(reform, redcostsvec, dual_sol)
Expand All @@ -374,6 +375,7 @@ function solve_sps_to_gencols!(
gen_status, new_sp_sol_ids, sp_sol_ids_to_activate, sp_dual_contrib = solve_sp_to_gencol!(
algo, masterform, spdata, dual_sol, sp_lbs[spuid], sp_ubs[spuid]
)
gen_statuses[spuid] = gen_status
if gen_status # else Sp is infeasible: contrib = Inf
recorded_sp_solution_ids[spuid] = new_sp_sol_ids
sp_solution_to_activate[spuid] = sp_sol_ids_to_activate
Expand All @@ -385,6 +387,7 @@ function solve_sps_to_gencols!(
gen_status, new_sp_sol_ids, sp_sol_ids_to_activate, sp_dual_contrib = solve_sp_to_gencol!(
algo, masterform, spdata, dual_sol, sp_lbs[spuid], sp_ubs[spuid]
)
gen_statuses[spuid] = gen_status
if gen_status # else Sp is infeasible: contrib = Inf
recorded_sp_solution_ids[spuid] = new_sp_sol_ids
sp_solution_to_activate[spuid] = sp_sol_ids_to_activate
Expand All @@ -394,6 +397,12 @@ function solve_sps_to_gencols!(
end
### END LOOP TO BE PARALLELIZED

for (spuid, status) in gen_statuses
if !status
return -1, DualBound(masterform)
end
end

nb_new_cols = 0
for (spuid, spdata) in spsdatas
dual_bound_contrib += sp_dual_bound_contribs[spuid]
Expand All @@ -403,7 +412,7 @@ function solve_sps_to_gencols!(
nb_new_cols += 1
end
end
return (nb_new_cols, dual_bound_contrib)
return nb_new_cols, dual_bound_contrib
end

function compute_master_db_contrib(
Expand Down
17 changes: 16 additions & 1 deletion test/full_instances_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,23 @@ function generalized_assignment_tests()
@test abs(JuMP.objective_value(problem) - 580.0) <= 0.00001
end

@testset "gap with infeasible master" begin
data = CLD.GeneralizedAssignment.data("master_infeas.txt")

coluna = JuMP.optimizer_with_attributes(
Coluna.Optimizer,
"params" => CL.Params(solver = ClA.TreeSearchAlgorithm()),
"default_optimizer" => GLPK.Optimizer
)

problem, x, dec = CLD.GeneralizedAssignment.model(data, coluna)

JuMP.optimize!(problem)
@test MOI.get(problem.moi_backend.optimizer, MOI.TerminationStatus()) == MOI.INFEASIBLE
end

@testset "gap with infeasible subproblem" begin
data = CLD.GeneralizedAssignment.data("root_infeas.txt")
data = CLD.GeneralizedAssignment.data("sp_infeas.txt")

coluna = JuMP.optimizer_with_attributes(
Coluna.Optimizer,
Expand Down