Skip to content

Commit

Permalink
ok
Browse files Browse the repository at this point in the history
  • Loading branch information
guimarqu committed Aug 19, 2022
1 parent 0f721a1 commit c882110
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 109 deletions.
24 changes: 24 additions & 0 deletions docs/src/api/algorithm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Algorithm API

An algorithm is a procedure that given a model and and input performs some operations and
returns an output.

```@docs
run!
```

Parameters of an algorithm may contain its child algorithms which used by it. Therefore,
the algoirthm tree is formed, in which the root is the algorithm called to solver the model
(root algorithm should be an optimization algorithm, see below).

Algorithms are divided into two types : "manager algorithms" and "worker algorithms".
Worker algorithms just continue the calculation. They do not store and restore units
as they suppose it is done by their master algorithms. Manager algorithms may divide
the calculation flow into parts. Therefore, they store and restore units to make sure
that their child worker algorithms have units prepared.
A worker algorithm cannot have child manager algorithms.

Examples of manager algorithms : TreeSearchAlgorithm (which covers both BCP algorithm and
diving algorithm), conquer algorithms, strong branching, branching rule algorithms
(which create child nodes). Examples of worker algorithms : column generation, SolveIpForm,
SolveLpForm, cut separation, pricing algorithms, etc.
8 changes: 5 additions & 3 deletions src/Algorithm/Algorithm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@ import Base: push!
include("utilities/optimizationstate.jl")
include("utilities/helpers.jl")

# Abstract algorithm
# API on top of storage API
include("data.jl")

# Algorithm interface
include("interface.jl")

# Tree search interface
include("treesearch/interface.jl")
include("treesearch/explore.jl")

# Storage units & records implementation
include("formstorages.jl")

# Basic algorithms
Expand All @@ -41,9 +44,8 @@ include("colgen.jl")
include("benders.jl")
include("preprocessing.jl")

# Algorithms and structures used by the tree search algorithm
# Conquer
include("conquer.jl")
include("divide.jl")

# Here include divide algorithms
include("branching/interface.jl")
Expand Down
53 changes: 0 additions & 53 deletions src/Algorithm/conquer.jl
Original file line number Diff line number Diff line change
@@ -1,56 +1,3 @@
"""
AbstractConquerInput
Input of a conquer algorithm used by the tree search algorithm.
Contains the node in the search tree and the collection of units to restore
before running the conquer algorithm. This collection of units is passed
in the input so that it is not obtained each time the conquer algorithm runs.
"""

abstract type AbstractConquerInput end

function get_node(i::AbstractConquerInput)
@warn "get_node(::$(typeof(i))) not implemented."
return nothing
end

function get_units_to_restore(i::AbstractConquerInput)
@warn "get_units_to_restore(::$(typeof(i))) not implemented."
return nothing
end

function run_conquer(i::AbstractConquerInput)
@warn "run_conquer(::$(typeof(i))) not implemented."
return nothing
end

"""
AbstractConquerAlgorithm
This algorithm type is used by the tree search algorithm to update the incumbents and the formulation.
For the moment, a conquer algorithm can be run only on reformulation.
A conquer algorithm should restore records of storage units using `restore_from_records!(conquer_input)`
- each time it runs in the beginning
- each time after calling a child manager algorithm
"""
abstract type AbstractConquerAlgorithm <: AbstractAlgorithm end

# conquer algorithms are always manager algorithms (they manage storing and restoring units)
ismanager(algo::AbstractConquerAlgorithm) = true

function run!(algo::AbstractConquerAlgorithm, env::Env, reform::Reformulation, input::AbstractConquerInput)
algotype = typeof(algo)
error(string("Method run! which takes as parameters Reformulation and ConquerInput ",
"is not implemented for algorithm $algotype.")
)
end

# this function is needed in strong branching (to have a better screen logging)
isverbose(algo::AbstractConquerAlgorithm) = false

# this function is needed to check whether the best primal solution should be copied to the node optimization state
exploits_primal_solutions(algo::AbstractConquerAlgorithm) = false

####################################################################
# ParameterisedHeuristic
####################################################################
Expand Down
41 changes: 0 additions & 41 deletions src/Algorithm/divide.jl
Original file line number Diff line number Diff line change
@@ -1,41 +0,0 @@
"""
Input of a divide algorithm used by the tree search algorithm.
Contains the parent node in the search tree for which children should be generated.
"""
abstract type AbstractDivideInput end

function get_parent(i::AbstractDivideInput)
@warn "get_parent(::$(typeof(i))) not implemented."
return nothing
end

function get_opt_state(i::AbstractDivideInput)
@warn "get_opt_state(::$(typeof(i))) not implemented."
return nothing
end

"""
Output of a divide algorithm used by the tree search algorithm.
Should contain the vector of generated nodes.
"""
struct DivideOutput{N<:AbstractNode}
children::Vector{N}
optstate::OptimizationState
end

get_children(output::DivideOutput) = output.children
get_opt_state(output::DivideOutput) = output.optstate

"""
This algorithm type is used by the tree search algorithm to generate nodes.
"""
abstract type AbstractDivideAlgorithm <: AbstractAlgorithm end

# divide algorithms are always manager algorithms (they manage storing and restoring units)
ismanager(algo::AbstractDivideAlgorithm) = true

run!(algo::AbstractDivideAlgorithm, ::Env, model::AbstractModel, input::AbstractDivideInput) =
error("Method run! in not defined for divide algorithm $(typeof(algo)), model $(typeof(model)), and input $(typeof(input)).")

# this function is needed to check whether the best primal solution should be copied to the node optimization state
exploits_primal_solutions(algo::AbstractDivideAlgorithm) = false
96 changes: 96 additions & 0 deletions src/Algorithm/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,108 @@ get_units_usage(::AbstractAlgorithm, ::AbstractModel) = Tuple{AbstractModel, Uni
# Conquer Algorithm API
############################################################################################

"""
AbstractConquerInput
Input of a conquer algorithm used by the tree search algorithm.
Contains the node in the search tree and the collection of units to restore
before running the conquer algorithm. This collection of units is passed
in the input so that it is not obtained each time the conquer algorithm runs.
"""
abstract type AbstractConquerInput end

function get_node(i::AbstractConquerInput)
@warn "get_node(::$(typeof(i))) not implemented."
return nothing
end

function get_units_to_restore(i::AbstractConquerInput)
@warn "get_units_to_restore(::$(typeof(i))) not implemented."
return nothing
end

function run_conquer(i::AbstractConquerInput)
@warn "run_conquer(::$(typeof(i))) not implemented."
return nothing
end

"""
AbstractConquerAlgorithm
This algorithm type is used by the tree search algorithm to update the incumbents and the formulation.
For the moment, a conquer algorithm can be run only on reformulation.
A conquer algorithm should restore records of storage units using `restore_from_records!(conquer_input)`
- each time it runs in the beginning
- each time after calling a child manager algorithm
"""
abstract type AbstractConquerAlgorithm <: AbstractAlgorithm end

# conquer algorithms are always manager algorithms (they manage storing and restoring units)
ismanager(algo::AbstractConquerAlgorithm) = true

function run!(algo::AbstractConquerAlgorithm, env::Env, reform::Reformulation, input::AbstractConquerInput)
algotype = typeof(algo)
error(string("Method run! which takes as parameters Reformulation and ConquerInput ",
"is not implemented for algorithm $algotype.")
)
end


# this function is needed in strong branching (to have a better screen logging)
isverbose(algo::AbstractConquerAlgorithm) = false

# this function is needed to check whether the best primal solution should be copied to the node optimization state
exploits_primal_solutions(algo::AbstractConquerAlgorithm) = false

############################################################################################
# Divide Algorithm API
############################################################################################

"""
Input of a divide algorithm used by the tree search algorithm.
Contains the parent node in the search tree for which children should be generated.
"""
abstract type AbstractDivideInput end

function get_parent(i::AbstractDivideInput)
@warn "get_parent(::$(typeof(i))) not implemented."
return nothing
end

function get_opt_state(i::AbstractDivideInput)
@warn "get_opt_state(::$(typeof(i))) not implemented."
return nothing
end

"""
Output of a divide algorithm used by the tree search algorithm.
Should contain the vector of generated nodes.
"""
struct DivideOutput{N}
children::Vector{N}
optstate::OptimizationState
end

get_children(output::DivideOutput) = output.children
get_opt_state(output::DivideOutput) = output.optstate

"""
This algorithm type is used by the tree search algorithm to generate nodes.
"""
abstract type AbstractDivideAlgorithm <: AbstractAlgorithm end

# divide algorithms are always manager algorithms (they manage storing and restoring units)
ismanager(algo::AbstractDivideAlgorithm) = true

run!(algo::AbstractDivideAlgorithm, ::Env, model::AbstractModel, input::AbstractDivideInput) =
error("Method run! in not defined for divide algorithm $(typeof(algo)), model $(typeof(model)), and input $(typeof(input)).")

# this function is needed to check whether the best primal solution should be copied to the node optimization state
exploits_primal_solutions(algo::AbstractDivideAlgorithm) = false

############################################################################################
# Optimization Algorithm API
############################################################################################

"""
AbstractOptimizationAlgorithm
Expand Down
24 changes: 12 additions & 12 deletions test/ColunaTests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,20 @@ module ColunaTests
end
end

########################################################################################
# Integration tests
########################################################################################
dirpath = joinpath(@__DIR__, "integration")
for filename in readdir(dirpath)
include(joinpath(dirpath, filename))
end

# ########################################################################################
# # Integration tests
# # MOI integration tests
# ########################################################################################
# dirpath = joinpath(@__DIR__, "integration")
# for filename in readdir(dirpath)
# include(joinpath(dirpath, filename))
# end

# # ########################################################################################
# # # MOI integration tests
# # ########################################################################################
# @testset "MOI integration" begin
# include("MathOptInterface/MOI_wrapper.jl")
# end
@testset "MOI integration" begin
include("MathOptInterface/MOI_wrapper.jl")
end

########################################################################################
# E2E tests
Expand Down

0 comments on commit c882110

Please sign in to comment.