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)^2Once 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 = nothingWe 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: GAYou 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)
0Complete 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