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

Introducing Env #443

Merged
merged 4 commits into from
Feb 4, 2021
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
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ version = "0.3.4"
[deps]
BlockDecomposition = "6cde8614-403a-11e9-12f1-c10d0f0caca0"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
DynamicSparseArrays = "8086fd22-9a0c-46a5-a6c8-6e24676501fe"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
Expand Down
5 changes: 3 additions & 2 deletions src/Algorithm/basic/cutcallback.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ end

struct RobustCutCallbackContext
form::Formulation
env::Env
proj_sol::PrimalSolution # ordered non zero but O(log^2(n)) lookup time
proj_sol_dict::Dict{VarId, Float64} # O(1) lookup time
viol_vals::Vector{Float64}
Expand All @@ -30,7 +31,7 @@ function get_storages_usage(algo::CutCallbacks, form::Formulation{MathProg.Abstr
return [(form, MasterCutsStoragePair, READ_AND_WRITE)]
end

function run!(algo::CutCallbacks, data::ModelData, input::CutCallbacksInput)
function run!(algo::CutCallbacks, env::Env, data::ModelData, input::CutCallbacksInput)
form = getmodel(data)
nb_cuts = 0
robust_generators = get_robust_constr_generators(form)
Expand All @@ -39,7 +40,7 @@ function run!(algo::CutCallbacks, data::ModelData, input::CutCallbacksInput)

projsol1 = proj_cols_on_rep(input.primalsol, form)
projsol2 = Dict{VarId, Float64}(varid => val for (varid, val) in projsol1)
context = RobustCutCallbackContext(form, projsol1, projsol2, Float64[])
context = RobustCutCallbackContext(form, env, projsol1, projsol2, Float64[])

for constrgen in robust_generators
if constrgen.kind == Facultative && algo.call_robust_facultative
Expand Down
6 changes: 3 additions & 3 deletions src/Algorithm/basic/solveipform.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function check_if_optimizer_supports_ip(optimizer::MoiOptimizer)
end
check_if_optimizer_supports_ip(optimizer::UserOptimizer) = true

function run!(algo::SolveIpForm, data::ModelData, input::OptimizationInput)::OptimizationOutput
function run!(algo::SolveIpForm, env::Env, data::ModelData, input::OptimizationInput)::OptimizationOutput
form = getmodel(data)

result = OptimizationState(
Expand Down Expand Up @@ -100,8 +100,8 @@ function run!(algo::SolveIpForm, data::ModelData, input::OptimizationInput)::Opt
return OptimizationOutput(result)
end

run!(algo::SolveIpForm, data::ReformData, input::OptimizationInput) =
run!(algo, getmasterdata(data), input)
run!(algo::SolveIpForm, env::Env, data::ReformData, input::OptimizationInput) =
run!(algo, env, getmasterdata(data), input)

function termination_status!(result::OptimizationState, optimizer::MoiOptimizer)
terminationstatus = MOI.get(getinner(optimizer), MOI.TerminationStatus())
Expand Down
2 changes: 1 addition & 1 deletion src/Algorithm/basic/solvelpform.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function optimize_lp_form!(
return
end

function run!(algo::SolveLpForm, data::ModelData, input::OptimizationInput)::OptimizationOutput
function run!(algo::SolveLpForm, env::Env, data::ModelData, input::OptimizationInput)::OptimizationOutput
form = getmodel(data)
result = OptimizationState(form)

Expand Down
38 changes: 18 additions & 20 deletions src/Algorithm/benders.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ function get_storages_usage(algo::BendersCutGeneration, reform::Reformulation)
for (id, spform) in get_benders_sep_sps(reform)
push!(storages_usage, (spform, StaticVarConstrStoragePair, READ_ONLY))
end

return storages_usage
end

Expand Down Expand Up @@ -51,14 +50,14 @@ end

getoptstate(data::BendersCutGenRuntimeData) = data.optstate

function run!(algo::BendersCutGeneration, rfdata::ReformData, input::OptimizationInput)::OptimizationOutput

function run!(
algo::BendersCutGeneration, env::Env, rfdata::ReformData, input::OptimizationInput
)::OptimizationOutput
reform = getreform(rfdata)
relax_integrality!(getmaster(reform))
bndata = BendersCutGenRuntimeData(reform, getoptstate(input))
@logmsg LogLevel(-1) "Run BendersCutGeneration."
Base.@time bend_rec = bend_cutting_plane_main_loop!(algo, bndata, reform)

Base.@time bend_rec = bend_cutting_plane_main_loop!(algo, env, bndata, reform)
return OptimizationOutput(bndata.optstate)
end

Expand Down Expand Up @@ -127,7 +126,6 @@ function update_benders_sp_problem!(
setcurcost!(spform, var, rc)
end
end

return false
end

Expand Down Expand Up @@ -224,7 +222,7 @@ function compute_benders_sp_lagrangian_bound_contrib(
end

function solve_sp_to_gencut!(
algo::BendersCutGeneration, algdata::BendersCutGenRuntimeData,
algo::BendersCutGeneration, env::Env, algdata::BendersCutGenRuntimeData,
masterform::Formulation, spform::Formulation,
master_primal_sol::PrimalSolution, master_dual_sol::DualSolution,
up_to_phase::FormulationPhase
Expand Down Expand Up @@ -268,7 +266,7 @@ function solve_sp_to_gencut!(
# Solve sub-problem and insert generated cuts in master
# @logmsg LogLevel(-3) "optimizing benders_sp prob"
TO.@timeit Coluna._to "Bender Sep SubProblem" begin
optstate = run!(SolveLpForm(get_dual_solution = true), ModelData(spform), OptimizationInput(OptimizationState(spform)))
optstate = run!(SolveLpForm(get_dual_solution = true), env, ModelData(spform), OptimizationInput(OptimizationState(spform)))
end

optresult = getoptstate(optstate)
Expand Down Expand Up @@ -350,7 +348,7 @@ end


function solve_sps_to_gencuts!(
algo::BendersCutGeneration, algdata::BendersCutGenRuntimeData,
algo::BendersCutGeneration, env::Env, algdata::BendersCutGenRuntimeData,
reform::Reformulation, master_primalsol::PrimalSolution,
master_dualsol::DualSolution, up_to_phase::FormulationPhase
)
Expand All @@ -371,7 +369,7 @@ function solve_sps_to_gencuts!(
for (spuid, spform) in sps
recorded_sp_dual_solution_ids[spuid] = Vector{ConstrId}()
gen_status, spsol_relaxed, recorded_dual_solution_ids, benders_sp_primal_bound_contrib, benders_sp_lagrangian_bound_contrib = solve_sp_to_gencut!(
algo, algdata, masterform, spform,
algo, env, algdata, masterform, spform,
master_primalsol, master_dualsol,
up_to_phase
)
Expand Down Expand Up @@ -419,15 +417,15 @@ function update_lagrangian_pb!(algdata::BendersCutGenRuntimeData, reform::Reform
return lagran_bnd
end

function solve_relaxed_master!(master::Formulation)
function solve_relaxed_master!(master::Formulation, env::Env)
elapsed_time = @elapsed begin
optresult = TO.@timeit Coluna._to "relaxed master" run!(SolveLpForm(get_dual_solution = true), ModelData(master), OptimizationInput(OptimizationState(master)))
optresult = TO.@timeit Coluna._to "relaxed master" run!(SolveLpForm(get_dual_solution = true), env, ModelData(master), OptimizationInput(OptimizationState(master)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

big line?

end
return optresult, elapsed_time
end

function generatecuts!(
algo::BendersCutGeneration, algdata::BendersCutGenRuntimeData, reform::Reformulation,
algo::BendersCutGeneration, env::Env, algdata::BendersCutGenRuntimeData, reform::Reformulation,
master_primal_sol::PrimalSolution, master_dual_sol::DualSolution, phase::FormulationPhase
)::Tuple{Int, Bool, PrimalBound}
masterform = getmaster(reform)
Expand All @@ -437,7 +435,7 @@ function generatecuts!(
## TODO stabilization : move the following code inside a loop
nb_new_cuts, spsols_relaxed, pb_correction, sp_pb_contrib =
solve_sps_to_gencuts!(
algo, algdata, reform, master_primal_sol, filtered_dual_sol, phase
algo, env, algdata, reform, master_primal_sol, filtered_dual_sol, phase
)
update_lagrangian_pb!(algdata, reform, master_dual_sol, sp_pb_contrib)
if nb_new_cuts < 0
Expand All @@ -453,7 +451,7 @@ function generatecuts!(
end

function bend_cutting_plane_main_loop!(
algo::BendersCutGeneration, algdata::BendersCutGenRuntimeData, reform::Reformulation
algo::BendersCutGeneration, env::Env, algdata::BendersCutGenRuntimeData, reform::Reformulation
)

nb_bc_iterations = 0
Expand All @@ -472,7 +470,7 @@ function bend_cutting_plane_main_loop!(
nb_new_cuts = 0
cur_gap = 0.0

optoutput, master_time = solve_relaxed_master!(masterform)
optoutput, master_time = solve_relaxed_master!(masterform, env)
optresult = getoptstate(optoutput)

if getterminationstatus(optresult) == INFEASIBLE
Expand Down Expand Up @@ -507,7 +505,7 @@ function bend_cutting_plane_main_loop!(
sp_time = @elapsed begin
nb_new_cuts, one_spsol_is_a_relaxed_sol, primal_bound =
generatecuts!(
algo, algdata, reform, master_primal_sol, master_dual_sol, up_to_phase
algo, env, algdata, reform, master_primal_sol, master_dual_sol, up_to_phase
)
end

Expand All @@ -523,7 +521,7 @@ function bend_cutting_plane_main_loop!(
cur_gap = gap(primal_bound, dual_bound)

print_benders_statistics(
bnd_optstate, nb_new_cuts, nb_bc_iterations, master_time, sp_time
env, bnd_optstate, nb_new_cuts, nb_bc_iterations, master_time, sp_time
)

if cur_gap < algo.optimality_tol
Expand Down Expand Up @@ -585,15 +583,15 @@ function bend_cutting_plane_main_loop!(
end

function print_benders_statistics(
optstate::OptimizationState, nb_new_cut::Int,
env::Env, optstate::OptimizationState, nb_new_cut::Int,
nb_bc_iterations::Int, mst_time::Float64, sp_time::Float64
)
mlp = getvalue(get_lp_dual_bound(optstate))
db = getvalue(get_ip_dual_bound(optstate))
pb = getvalue(get_ip_primal_bound(optstate))
@printf(
"<it=%3i> <et=%5.2f> <mst=%5.2f> <sp=%5.2f> <cuts=%i> <DB=%10.4f> <mlp=%10.4f> <PB=%10.4f>\n",
nb_bc_iterations, Coluna._elapsed_solve_time(), mst_time, sp_time, nb_new_cut, db, mlp, pb
nb_bc_iterations, elapsed_optim_time(env), mst_time, sp_time, nb_new_cut, db, mlp, pb
)
end

18 changes: 9 additions & 9 deletions src/Algorithm/branching/branchingalgo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ end
struct NoBranching <: AbstractDivideAlgorithm
end

function run!(algo::NoBranching, data::ReformData, input::DivideInput)::DivideOutput
function run!(algo::NoBranching, env::Env, data::ReformData, input::DivideInput)::DivideOutput
return DivideOutput([], OptimizationState(getmodel(getmasterdata(data))))
end

Expand Down Expand Up @@ -90,7 +90,7 @@ function exploits_primal_solutions(algo::StrongBranching)
end

function perform_strong_branching_with_phases!(
algo::StrongBranching, data::ReformData, input::DivideInput, groups::Vector{BranchingGroup}
algo::StrongBranching, env::Env, data::ReformData, input::DivideInput, groups::Vector{BranchingGroup}
)::OptimizationState

parent = getparent(input)
Expand Down Expand Up @@ -131,7 +131,7 @@ function perform_strong_branching_with_phases!(
#TO DO: verify if time limit is reached

if phase_index == 1
generate_children!(group, data, parent)
generate_children!(group, env, data, parent)
else
regenerate_children!(group, parent)
end
Expand All @@ -154,7 +154,7 @@ function perform_strong_branching_with_phases!(
update_ip_primal!(getoptstate(node), sbstate, exploitsprimalsolutions)

apply_conquer_alg_to_node!(
node, current_phase.conquer_algo, data, conquer_storages_to_restore
node, current_phase.conquer_algo, env, data, conquer_storages_to_restore
)

update_all_ip_primal_solutions!(sbstate, getoptstate(node))
Expand Down Expand Up @@ -194,7 +194,7 @@ function perform_strong_branching_with_phases!(
return sbstate
end

function run!(algo::StrongBranching, data::ReformData, input::DivideInput)::DivideOutput
function run!(algo::StrongBranching, env::Env, data::ReformData, input::DivideInput)::DivideOutput
parent = getparent(input)
optstate = getoptstate(parent)

Expand Down Expand Up @@ -251,7 +251,7 @@ function run!(algo::StrongBranching, data::ReformData, input::DivideInput)::Divi
min_priority = priority

# generate candidates
output = run!(rule, data, BranchingRuleInput(
output = run!(rule, env, data, BranchingRuleInput(
original_solution, true, nb_candidates_needed, algo.selection_criterion,
local_id, algo.int_tol
))
Expand All @@ -260,7 +260,7 @@ function run!(algo::StrongBranching, data::ReformData, input::DivideInput)::Divi
local_id = output.local_id

if projection_is_possible(master) && extended_solution !== nothing
output = run!(rule, data, BranchingRuleInput(
output = run!(rule, env, data, BranchingRuleInput(
extended_solution, false, nb_candidates_needed, algo.selection_criterion,
local_id, algo.int_tol
))
Expand All @@ -287,11 +287,11 @@ function run!(algo::StrongBranching, data::ReformData, input::DivideInput)::Divi

#in the case of simple branching, it remains to generate the children
if isempty(algo.phases)
generate_children!(kept_branch_groups[1], data, parent)
generate_children!(kept_branch_groups[1], env, data, parent)
return DivideOutput(kept_branch_groups[1].children, OptimizationState(getmaster(reform)))
end

sbstate = perform_strong_branching_with_phases!(algo, data, input, kept_branch_groups)
sbstate = perform_strong_branching_with_phases!(algo, env, data, input, kept_branch_groups)

return DivideOutput(kept_branch_groups[1].children, sbstate)
end
7 changes: 4 additions & 3 deletions src/Algorithm/branching/branchinggroup.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ abstract type AbstractBranchingCandidate end

getdescription(candidate::AbstractBranchingCandidate) = ""
generate_children!(
candidate::AbstractBranchingCandidate, lhs::Float64, data::ReformData, node::Node
candidate::AbstractBranchingCandidate, lhs::Float64, env::Env, data::ReformData,
node::Node
) = nothing

"""
Expand Down Expand Up @@ -42,9 +43,9 @@ get_lhs_distance_to_integer(group::BranchingGroup) =
min(group.lhs - floor(group.lhs), ceil(group.lhs) - group.lhs)

function generate_children!(
group::BranchingGroup, data::ReformData, parent::Node
group::BranchingGroup, env::Env, data::ReformData, parent::Node
)
group.children = generate_children(group.candidate, group.lhs, data, parent)
group.children = generate_children(group.candidate, group.lhs, env, data, parent)
return
end

Expand Down
2 changes: 1 addition & 1 deletion src/Algorithm/branching/branchingrule.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ abstract type AbstractBranchingRule <: AbstractAlgorithm end
ismanager(algo::AbstractBranchingRule) = true

function run!(
rule::AbstractBranchingRule, data::AbstractData, input::BranchingRuleInput
rule::AbstractBranchingRule, env::Env, data::AbstractData, input::BranchingRuleInput
)::BranchingRuleOutput
algotype = typeof(rule)
error("Method run! in not defined for branching rule $(typeof(rule)), data $(typeof(data)), and input $(typeof(input)).")
Expand Down
9 changes: 5 additions & 4 deletions src/Algorithm/branching/varbranching.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ end
getdescription(candidate::VarBranchingCandidate) = candidate.description

function generate_children(
candidate::VarBranchingCandidate, lhs::Float64, data::ReformData, parent::Node
candidate::VarBranchingCandidate, lhs::Float64, env::Env, data::ReformData, parent::Node
)
master = getmaster(getreform(data))
var = getvar(master, candidate.varid)
Expand All @@ -33,7 +33,7 @@ function generate_children(
master, string(
"branch_geq_", getdepth(parent), "_", getname(master,candidate.varid)
), MasterBranchOnOrigVarConstr;
sense = Greater, rhs = ceil(lhs), loc_art_var = true,
sense = Greater, rhs = ceil(lhs), loc_art_var_abs_cost = env.params.local_art_var_cost,
members = Dict{VarId,Float64}(candidate.varid => 1.0)
)
end
Expand All @@ -47,7 +47,8 @@ function generate_children(
master, string(
"branch_leq_", getdepth(parent), "_", getname(master,candidate.varid)
), MasterBranchOnOrigVarConstr;
sense = Less, rhs = floor(lhs), loc_art_var = true,
sense = Less, rhs = floor(lhs),
loc_art_var_abs_cost = env.params.local_art_var_cost,
members = Dict{VarId,Float64}(candidate.varid => 1.0)
)
end
Expand Down Expand Up @@ -75,7 +76,7 @@ function get_storages_usage(algo::VarBranchingRule, reform::Reformulation)
end

function run!(
rule::VarBranchingRule, data::ReformData, input::BranchingRuleInput
rule::VarBranchingRule, env::Env, data::ReformData, input::BranchingRuleInput
)::BranchingRuleOutput
# variable branching works only for the original solution
!input.isoriginalsol && return BranchingRuleOutput(input.local_id, Vector{BranchingGroup}())
Expand Down
Loading