Optimization
To show how the Evolutionary package can be used, we minimize the Rosenbrock function, a classical test problem for numerical optimization. We'll assume that you've already installed the Evolutionary package using Julia's package manager.
First, we load Evolutionary and define the Rosenbrock function:
using Evolutionary
f(x) = (1.0 - x[1])^2 + 100.0 * (x[2] - x[1]^2)^2
Once we've defined this function, we can find the minimizer (the input that minimizes the objective) and the minimum (the value of the objective at the minimizer) using any of our favorite optimization algorithms. With a function defined, we just specify a form of an individual x
of the population for an evolutionary algorithm, and call optimize
with a starting individual x0
and a particular optimization algorithm, e.g. CMAES()
:
x0 = [0.0, 0.0];
Evolutionary.optimize(f, x0, CMAES())
Configurable options
There are several options that simply take on some default values if the user doesn't provide any.
Algorithm options
There are different algorithms available in Evolutionary
, and they are all listed below. Notice that the constructors are written without input here, but they generally take keywords to tweak the way they work. See the pages describing each solver for more detail.
General options
In addition to the algorithm, you can alter the behavior of the optimization procedure by using the following Options
keyword arguments:
Evolutionary.Options
— TypeConfigurable options with defaults:
abstol::Float64 = 1e-32
reltol::Float64 = 1e-32
successive_f_tol::Integer = 10
iterations::Integer = 1000
store_trace::Bool = false
show_trace::Bool = false
show_every::Integer = 1
callback::TCallback = nothing
We currently recommend the statically dispatched interface by using the Evolutionary.Options
constructor:
res = Evolutionary.optimize(x->-sum(x),
BitVector(zeros(3)),
GA(),
Evolutionary.Options(iterations=10))
Obtaining results
After we have our results in res
object, we can use the API for getting optimization results. This consists of a collection of functions. They are not exported, so they have to be prefixed by Evolutionary.
. Say we do the following optimization:
julia> res = Evolutionary.optimize(x->-sum(x), BitVector(zeros(3)), GA())
* Status: success
* Candidate solution
Minimizer: [false, false, false]
Minimum: 0
Iterations: 11
* Found with
Algorithm: GA
You can inspect the result by using a collection of the auxiliary functions, e.g. the minimizer
and minimum
of the objective functions, which can be found using
julia> Evolutionary.minimizer(res)
3-element BitArray{1}:
0
0
0
julia> Evolutionary.minimum(res)
0
Complete list of functions
An OptimizationResults
interface for representing an optimization result.
Evolutionary.OptimizationResults
— TypeAbstract evolutionary optimization result type
Base.summary
— Methodsummary(result)
Shows the optimization algorithm that produced this result
.
Evolutionary.minimizer
— Methodminimizer(result)
A minimizer object from the optimization result
.
Base.minimum
— Methodminimum(result)
A minimum value from the optimization result
.
Evolutionary.iterations
— Methoditerations(result)
A number of iterations to reach the minimum.
Evolutionary.iteration_limit_reached
— Methoditeration_limit_reached(result)
Returns true
if the iteration limit was reached.
Evolutionary.trace
— Methodtrace(result)
Returns a trace of optimization states from the optimization result
.
NLSolversBase.f_calls
— Methodf_calls(result)
Returns a number of an objective function calls.
Evolutionary.tol
— Methodtol(result)
Returns an absolute tollerance value of the optimization result
.
An implementation of the result object for evolutionary optimizations.
Evolutionary.EvolutionaryOptimizationResults
— TypeEvolutionary optimization result type
Evolutionary.converged
— Methodconverged(result)
Returns true
if the optimization sucesfully coverged to a minimum value.
Evolutionary.tol
— Methodtol(result)
Returns an absolute tollerance value of the optimization result
.
Trace
When store_trace
and/or show_trace
options are set to true
in the Option
(@ref) object, an optimization trace is either captured and/or shown on the screen. By default, only the current state minimum value is displayed in the trace. In order to extend trace record, you need to override trace!
function providing specialize function behavior on one of specific parameters.
Evolutionary.trace!
— Methodtrace!(record::Dict{String,Any}, objfun, state, population, method, options)
Update the trace record
. This function allows to supplement an additional information into the optimization algorithm trace by modifing a trace record
. It can be overwiden by specifing particular parameter types.
Commonly, you would define a specializations of a state
, population
, or method
parameters of trace!
function, e.g.
function trace!(record::Dict{String,Any}, objfun, state, population, method::CMAES, options)
record["σ"] = state.σ
end