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

Remove UserInfo #751

Merged
merged 1 commit into from
Nov 29, 2022
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
6 changes: 0 additions & 6 deletions src/Algorithm/branching/branchingalgo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,8 @@ Chooses the best candidate according to a selection criterion and generates the
selection_criterion::AbstractSelectionCriterion = MostFractionalCriterion()
rules = [PrioritisedBranchingRule(SingleVarBranchingRule(), 1.0, 1.0)]
int_tol = 1e-6
root_user_info::AbstractNodeUserInfo = DummyUserInfo()
end

get_root_user_info(algo::Branching) = algo.root_user_info

get_selection_nb_candidates(::Branching) = 1

struct BranchingContext{SelectionCriterion<:AbstractSelectionCriterion} <: AbstractDivideContext
Expand Down Expand Up @@ -114,11 +111,8 @@ restrict the number of retained candidates until only one is left.
selection_criterion::AbstractSelectionCriterion = MostFractionalCriterion()
verbose = true
int_tol = 1e-6
root_user_info::AbstractNodeUserInfo = DummyUserInfo()
end

get_root_user_info(algo::StrongBranching) = algo.root_user_info

## Implementation of Algorithm API.

# StrongBranching does not use any storage unit itself,
Expand Down
21 changes: 8 additions & 13 deletions src/Algorithm/conquer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ struct NodeFinalizer
end

####################################################################
# BeforeCutGenUserAlgo
# BeforeCutGenAlgo
####################################################################

struct BeforeCutGenUserAlgo <: AbstractConquerAlgorithm
"Algorithm called before cut generation."
struct BeforeCutGenAlgo <: AbstractConquerAlgorithm
algorithm::AbstractOptimizationAlgorithm
name::String
end
Expand Down Expand Up @@ -103,7 +104,7 @@ Parameters :
@with_kw struct ColCutGenConquer <: AbstractConquerAlgorithm
stages::Vector{ColumnGeneration} = [ColumnGeneration()]
primal_heuristics::Vector{ParameterizedHeuristic} = [ParamRestrictedMasterHeuristic()]
before_cutgen_user_algorithm::Union{Nothing, BeforeCutGenUserAlgo} = nothing
before_cutgen_user_algorithm::Union{Nothing, BeforeCutGenAlgo} = nothing
node_finalizer::Union{Nothing, NodeFinalizer} = nothing
preprocess = nothing
cutgen = CutCallbacks()
Expand Down Expand Up @@ -202,24 +203,23 @@ Returns `true` if the conquer algorithm continues.
function run_colcutgen!(ctx::ColCutGenContext, env, reform, node_state)
nb_cut_rounds = 0
run_conquer = true
cuts_were_added = true
master_changed = true
master_changed = true # stores value returned by the algorithm called before cut gen.
cuts_were_added = true # stores value returned by cut gen.
while run_conquer && (cuts_were_added || master_changed)
for (stage_index, colgen) in Iterators.reverse(Iterators.enumerate(ctx.params.stages))
# print stage_index
# TODO: print stage_index
run_conquer = run_colgen!(ctx, colgen, env, reform, node_state)
if !run_conquer
return false
end
end

master_changed = false
before_cutgen_user_algorithm = ctx.params.before_cutgen_user_algorithm
if !isnothing(before_cutgen_user_algorithm)
master_changed = run_before_cutgen_user_algo!(
ctx, before_cutgen_user_algorithm, env, reform, node_state
)
else
master_changed = false
end

sol = get_best_lp_primal_sol(node_state)
Expand Down Expand Up @@ -392,12 +392,7 @@ end
function run!(algo::ColCutGenConquer, env::Env, reform::Reformulation, input::AbstractConquerInput)
!run_conquer(input) && return
ctx = new_context(type_of_context(algo), algo, reform, input)
node = get_node(input)
parent = get_parent(node)
info = isnothing(parent) ? get_user_info(node) : get_user_info(parent)
MathProg.set_user_info!(reform, MathProg.copy_info(info))
run_colcutgen_conquer!(ctx, env, reform, input)
set_user_info!(node, MathProg.get_user_info(reform))
return
end

Expand Down
2 changes: 0 additions & 2 deletions src/Algorithm/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,6 @@ abstract type AbstractDivideAlgorithm <: AbstractAlgorithm end
# divide algorithms are always manager algorithms (they manage storing and restoring units)
ismanager(algo::AbstractDivideAlgorithm) = true

get_root_user_info(::AbstractDivideAlgorithm) = DummyUserInfo()

@mustimplement "DivideAlgorithm" run!(::AbstractDivideAlgorithm, ::Env, ::AbstractModel, ::AbstractDivideInput)

# this function is needed to check whether the best primal solution should be copied to the node optimization state
Expand Down
9 changes: 2 additions & 7 deletions src/Algorithm/treesearch/branch_and_bound.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ mutable struct Node <: AbstractNode
branchdescription::String
records::Records
conquerwasrun::Bool
user_info::AbstractNodeUserInfo
end

getdepth(n::Node) = n.depth
Expand All @@ -23,9 +22,6 @@ set_records!(n::Node, records) = n.records = records

get_branch_description(n::Node) = n.branchdescription # printer

set_user_info!(n::Node, info::AbstractNodeUserInfo) = n.user_info = info
get_user_info(n::Node) = n.user_info

# Priority of nodes depends on the explore strategy.
get_priority(::AbstractExploreStrategy, ::Node) = error("todo")
get_priority(::DepthFirstStrategy, n::Node) = -n.depth
Expand All @@ -35,7 +31,7 @@ get_priority(::BestDualBoundStrategy, n::Node) = get_ip_dual_bound(n.optstate)
function Node(node::SbNode)
return Node(
node.depth, node.parent, node.optstate, node.branchdescription,
node.records, node.conquerwasrun, get_user_info(node.parent)
node.records, node.conquerwasrun
)
end

Expand Down Expand Up @@ -139,8 +135,7 @@ end
function new_root(sp::BaBSearchSpace, input)
nodestate = OptimizationState(getmaster(sp.reformulation), input, false, false)
return Node(
0, nothing, nodestate, "", create_records(sp.reformulation), false,
get_root_user_info(sp.divide)
0, nothing, nodestate, "", create_records(sp.reformulation), false
)
end

Expand Down
2 changes: 1 addition & 1 deletion src/MathProg/MathProg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export Problem, set_initial_dual_bound!, set_initial_primal_bound!,
# Methods related to Reformulation
export Reformulation, getmaster, add_dw_pricing_sp!, add_benders_sep_sp!, get_dw_pricing_sps,
set_reformulation!, get_benders_sep_sps, get_dw_pricing_sp_ub_constrid,
get_dw_pricing_sp_lb_constrid, setmaster!, get_user_info, set_user_info!
get_dw_pricing_sp_lb_constrid, setmaster!

# Methods related to formulations
export AbstractFormulation, Formulation, create_formulation!, getvar, getvars,
Expand Down
3 changes: 0 additions & 3 deletions src/MathProg/reformulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ ClB.getstorage(reform::Reformulation) = reform.storage

# methods specific to Formulation

set_user_info!(reform::Reformulation, info::AbstractNodeUserInfo) = reform.node_user_info = info
get_user_info(reform::Reformulation) = reform.node_user_info

"""
getobjsense(reformulation)

Expand Down
10 changes: 0 additions & 10 deletions src/MathProg/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,3 @@ used by algorithms. A formulation contains one storage unit
per storage unit type used by algorithms.
"""
abstract type AbstractFormulation <: AbstractModel end

"Sets the user info stored at the formulation"
function set_user_info!(::AbstractFormulation, ::AbstractNodeUserInfo)
return # Fall back that does nothing
end

"Gets the user info stored at the formulation"
function get_user_info(::AbstractFormulation)
return DummyUserInfo() # Fall back that gets a dummy user info
end
9 changes: 4 additions & 5 deletions test/integration/improve_relax_callback.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function ClA.get_branching_candidate_units_usage(::ClA.SingleVarBranchingCandida
return units_to_restore
end

ClA.ismanager(::ClA.BeforeCutGenUserAlgo) = false
ClA.ismanager(::ClA.BeforeCutGenAlgo) = false
ClA.ismanager(::ImproveRelaxationAlgo) = false

# Don't need this because `ToyNodeInfo` is bits
Expand All @@ -72,7 +72,7 @@ function ClA.get_units_usage(algo::ImproveRelaxationAlgo, reform::ClMP.Reformula
return units_usage
end

function ClA.get_child_algorithms(algo::ClA.BeforeCutGenUserAlgo, reform::ClMP.Reformulation)
function ClA.get_child_algorithms(algo::ClA.BeforeCutGenAlgo, reform::ClMP.Reformulation)
println("\e[42m THIS IS A CALL TO get_child_algorithm \e[00m")
child_algos = Tuple{ClA.AbstractAlgorithm, ClMP.AbstractModel}[]
push!(child_algos, (algo.algorithm, reform))
Expand Down Expand Up @@ -108,7 +108,7 @@ function test_improve_relaxation(; do_improve::Bool)
))
],
primal_heuristics = [],
before_cutgen_user_algorithm = ClA.BeforeCutGenUserAlgo(
before_cutgen_user_algorithm = ClA.BeforeCutGenAlgo(
ImproveRelaxationAlgo(
userfunc = call_improve_relaxation
),
Expand Down Expand Up @@ -174,8 +174,7 @@ function test_improve_relaxation(; do_improve::Bool)

# increment the user info value for testing
if !do_improve
info = ClMP.get_user_info(reform)
ClMP.set_user_info!(reform, ToyNodeInfo(info.value + 111))
unit.value += 111
end
return
end
Expand Down