Development
If you are contributing a new algorithm to this package, you need to know an internal API which allows to add a new algorithm without considerable changes to overall structure of the package.
Adding an algorithm
If you're contributing a new algorithm, you shouldn't need to touch any of the code in src/api/optimize.jl. You should rather add a file named (solver is the name of the solver) algo.jl
in src, and make sure that you define an optimizer parameters and state types, initial_population
that initializes a population of individual
objects, a state type that holds all variables that are (re)used throughout the iterative procedure, an initial_state
that initializes such a state, and an update_state!
method that does the actual work.
Algorithm
Every optimization algorithm have to implement an algorithm parameters type derived from AbstractOptimizer
type, e.g. struct Algo <: AbstractOptimizer end
, with appropriate fields, a default constructor with a keyword for each field.
Function initial_state
returns an initial state for the algorithm, see State section. Function update_state!
returns a Bool
value. If the state update is successfully completed then the function returns false
, otherwise true
.
Evolutionary.AbstractOptimizer
— TypeAbstract evolutionary optimizer algorithm
Evolutionary.initial_state
— FunctionInitialization of ES algorithm state
Initialization of CMA-ES algorithm state
Initialization of GA algorithm state
Initialization of DE algorithm state
Initialization of GP algorithm state
State
Every optimization algorithm have to implement a state type derived from AbstractOptimizerState
type, e.g. struct AlgoState <: AbstractOptimizerState end
. All derived types should implement value
and minimizer
functions
Evolutionary.AbstractOptimizerState
— TypeAbstract type for defining an optimizer state
Every algorithm have to implement a state type derived from this abstract type.
NLSolversBase.value
— Methodvalue(state)
Returns a minimum value of the current state
.
Evolutionary.minimizer
— Methodvalue(state)
Returns a minimizer object in the current state
.
Evolutionary.terminate
— Methodterminate(state)
Returns true
if the state
requires early termination.
Population
The evolutionary algorithms require a collection of individuals, population, which the algorithm constantly modifies. The population collection type must be derived from the AbstractVector
type. Function initial_population
is used for implementing a strategy of population collection initialization.
The initial_population
must accept two parameters:
method
, an algorithm object derived fromAbstractOptimizer
typeindividual
, a description of an individual template used to create the population
Following population initialization strategies are available:
Evolutionary.initial_population
— Functioninitial_population(method, individual::AbstractVector)
Initialize population by replicating the inividual
vector.
initial_population(method, individuals::AbstractVector{<:AbstractVector})
Initialize population from the collection of inividuals
vectors.
initial_population(method, individual::Function)
Initialize population from the inividual
function which returns an individual object.
initial_population(method, individual::AbstractMatrix)
Initialize population by replicating the inividual
matrix.
initial_population(method, bounds::ConstraintBounds)
Initialize a random population within the individual bounds
.
initial_population(m::TreeGP, expr::{Expr,Nothing}=nothing)
Initialize a random population of expressions derived from expr
.
Constraints
All constraints derived from the AbstractConstraints
abstract type. Usually the derived type wraps a ConstraintBounds
object, so the
Following methods can be overridden for the derived types:
NLSolversBase.value
— Methodvalue(c::AbstractConstraints, x)
Return a values of constraints for a variable x
given the set of constraints in the object c
.
Following auxiliary functions are available for every derived type of AbstractConstraints
.
Evolutionary.isfeasible
— Methodisfeasible(c::AbstractConstraints, x) -> Bool
Return true
if point x
is feasible, given the constraints object c
.
Package provides following additional constrains implementations.
Evolutionary.NoConstraints
— TypeType for an empty set of constratins
Evolutionary.MixedTypePenaltyConstraints
— TypeThis type provides an additional type constraints on the varaibles required for mixed integer optimization problmes.
Parallelization
For additional modes of parallelization of the objective function evaluation, add overrides of the value!
function. By default, the fitness of the population is calculated by the following function:
function value!(::Val{:serial}, fitness, objfun, population::AbstractVector{IT}) where {IT}
for i in 1:length(population)
fitness[i] = value(objfun, population[i])
end
end
The first symbolic value type parameter, :serial
, corresponds to the default value of the parallelization
of the Options
object. Any additional overrides with different value type parameters will be triggered by specifying a corresponded value type symbol in the Options.parallelization
field. A multi-threaded override of the above evaluation is provided.