Welcome to the Metaheuristic Designer API#
The library is built around a layered architecture. At the bottom you find
abstract interfaces (the “Base Classes” below) that define the contracts for every
optimisation component. On top of them sit concrete implementations:
pre-built initializers, operators, encodings, selection schemes, and full search
strategies. An Algorithm object glues everything together and runs the
optimisation loop.
If you want to jump straight into code, take a look at the Quick Start or follow the Algorithm Configuration guide – they show how to assemble a complete optimiser in a few lines.
For plotting your results, see the Plotting Tutorial.
Ready‑to‑run algorithms are provided by the Simple API page.
Base Classes#
These are the interfaces from which to inherit to implement a new component for any optimization algorithm.
Module name |
Description |
|---|---|
Prototype of a parameter that changes in value as iterations go on. |
|
Mixin used by interfaces to hold schedulable parameters. |
|
Abstract objective function with built‑in fitness conversion. |
|
Prototype of a constraint handler class. |
|
Prototype of a population initializer. |
|
Prototype of an encoding and decoding genotypes of the population. |
|
Prototype of a parent selection method. |
|
Prototype of a survivor selection method. |
|
Prototype of an operator on individuals. |
|
Prototype of a search strategy applied each generation. |
|
Prototype of a full optimization algorithm. |
Almost every interface works with the Population class internally.
Lambda Implementations#
Classes that allow implementing optimization modules with a lambda function, avoiding the need to inherit from a base class.
Module name |
Description |
|---|---|
Objective function from a function. |
|
Constraint Handler from a function. |
|
Population initializer from a function. |
|
Encoding from an encoding function and a decoding function. |
|
Parent selection from a function. |
|
Survivor selection from a function. |
|
Operator from a function. |
|
Full step of the algorithm defined componentwise by functions. |
For a complete walk‑through showing how to use these classes and the registration functions, see Custom Components.
Extended Encoding Classes#
When the genotype vector encodes more information than just the solution – such as a speed vector for PSO or adaptive algorithm parameters – you need these interfaces to handle the extra data.
Note that concrete implementations for specific algorithms (e.g. PSO) already exist.
Module name |
Description |
|---|---|
Encoding that splits the vector into a solution and a dictionary with the necessary extra data. |
|
Constraint handler that treats the solution and the extra data separately. |
|
Initializer that handles the solution and extra data with different distributions. |
|
Operator that applies different operations to the solution and the extra data. |
Parameter Schedules#
Many numerical parameters can be made schedulable by passing a SchedulableParameter subclass instead of a constant. The available schedules are:
Module name |
Description |
|---|---|
Changes the value linearly between two values. |
|
Sigmoid-shaped transition between two values. |
|
Keeps the initial value until progress crosses a threshold, then switches to the final value. |
|
Discrete steps defined by a list of (progress, value) pairs. |
|
Randomly picks a value between two bounds at each step. |
All schedules depend on the algorithm’s progress, a number between 0 and 1, to decide parameter values.
Initializers#
Implemented population initializers:
Module name |
Description |
|---|---|
Initializer that uses a uniform distribution. |
|
Initializer that uses a Gaussian distribution. |
|
Initializer that uses an exponential distribution. |
|
Initializer with a predefined population of individuals. |
|
Initializer that produces random permutations of n elements. |
|
Initializer based on uniform Latin Hypercube Sampling. |
|
Initializer that produces randomly permuted Sobol sequences. |
|
Initializer that produces Halton sequences. |
|
Initializer that randomly inserts seeded solutions with a given probability. |
|
Initializer that inserts seeded solutions with deterministically. |
|
Initializer that combines other initializers and draws from them with a given probability. |
|
Initializer that combines other initializers and draws from them in a deterministic pattern. |
Encodings#
Implemented encodings that transform between the internal genotype and the phenotype evaluated by the objective function:
Module name |
Description |
|---|---|
No change (identity encoding). |
|
Changes the datatype (e.g. float ↔ int ↔ boolean). |
|
Reshapes a vector to a tensor of a different shape. |
|
Reshapes a vector to an N×M×C image representation (channels last). |
|
Maps real numbers to probabilities via a sigmoid, enabling continuous operators on binary problems. |
|
Applies a sequence of other encodings in order. |
|
Extended encoding that stores a speed vector for PSO. |
|
Extended encoding that stores mutation strength(s) for self-adaptive evolution strategies. |
Selection Methods#
Parent and survivor selection are created with dedicated factory functions:
create_parent_selection()- returns aParentSelectioninstance.create_survivor_selection()- returns aSurvivorSelectioninstance.
To skip a selection step entirely, use NullParentSelection / NullSurvivorSelection.
The complete catalogue of available methods, their parameters, and instructions for registering custom ones are given on the API reference - Implemented Operators & Selection page (see Implemented Selection Methods).
To learn how to create custom parent or survivor selection methods and register them, consult the Custom Components page.
Operators#
Operators modify the genotype of individuals. They are created through the factory function
create_operator(), which accepts a string key
in the format "category.method" (e.g. "mutation.gaussian_mutation") and optional
keyword parameters.
from metaheuristic_designer.operators import create_operator
op = create_operator("mutation.gaussian_mutation", F=0.2, rng=42)
A few built-in operators do not follow the factory pattern:
Class |
Description |
|---|---|
Identity operator (no changes). |
|
Combines multiple operators sequentially. |
|
Applies different operators to different sets of components of the genotype vectors. |
|
Randomly selects one operator from a list each time it is applied. |
|
Base class for operators that handle extra per-individual parameters (e.g. self-adaptation). |
|
Gaussian process regression operator for Bayesian Optimisation. |
IMPORTANT: For the full catalogue of factory-available operators (mutation, crossover, permutation, DE,
swarm, …) and the probability distributions they support, see the
Operator Methods page. To see all available operators at runtime, call
list_operators().
For writing and registering your own operators, refer to the Custom Components guide.
Search Strategies#
A search strategy defines how one iteration of the optimisation loop is performed: it chooses parents, applies operators, and selects survivors. In practice it acts as a container for an initializer, an operator, and optional parent/survivor selection.
You can use one of the ready‑made strategies:
from metaheuristic_designer.strategies import GA
strategy = GA(
initializer=UniformInitializer(...),
mutation_op=create_operator("mutation.gaussian_mutation", F=0.1),
crossover_op=create_operator("crossover.uniform"),
parent_sel=create_parent_selection("tournament", amount=50),
survivor_sel=create_survivor_selection("elitism", amount=25),
)
or build your own by directly combining components with the general
SearchStrategy class:
strategy = SearchStrategy(
initializer=...,
operator=...,
parent_sel=...,
survivor_sel=...,
)
Both approaches result in an object that can be passed to Algorithm.
To construct a Search strategy, you can use one of the available prototypes:
Module name |
Description |
|---|---|
No‑op strategy (does nothing). |
|
Strategy that works improving single solutions. |
|
Strategy that preserves the size of the population. |
|
Variable‑size population based evolution. |
|
Strategy that has a parameter estimation step between parent selection and the evolution of the solutions. |
The following pre‑built strategies are also available:
Module name |
Description |
|---|---|
No‑op strategy (does nothing). |
|
Random search. |
|
Greedy hill climbing. |
|
Local search with a configurable number of iterations. |
|
Simulated annealing. |
|
Genetic Algorithm. |
|
Evolution Strategy. |
|
Differential Evolution. |
|
Particle Swarm Optimisation. |
|
Bernoulli Population‑Based Incremental Learning (EDA). |
|
Bernoulli Univariate Marginal Distribution Algorithm (EDA). |
|
Binomial PBIL. |
|
Binomial UMDA. |
|
Bayesian Optimisation with Gaussian processes. |
|
Covariance Matrix Adaptation Evolution Strategy. |
Additionally, we provide an interface to hybridize search strategies (only memetic algorithms at the moment):
Module name |
Description |
|---|---|
Strategy that uses a local search procedure to improve the best individuals after evolving them. |
Algorithms#
The Algorithm class runs the optimization loop. You pass it an objective
function, a search strategy, and optionally a stopping condition, reporter,
history tracker and checkpointer (see Algorithm Configuration).
algo = Algorithm(objfunc, strategy)
population = algo.optimize()
best_solution, best_obj = population.best_solution()
Built‑in algorithm variants:
Module name |
Description |
|---|---|
Default algorithm with the classic parent → perturb → evaluate → survivor loop. |
|
Benchmarks a set of algorithms. |
|
Benchmarks a set of search strategies. |
Stopping conditions can be defined as strings combining the following tokens with
and, or and parentheses. See the Algorithm Configuration page for how to set them.
Token |
Description |
|---|---|
|
Maximum number of objective function evaluations. |
|
Maximum number of iterations (generations). |
|
Wall-clock time limit in seconds. |
|
CPU time limit in seconds. |
|
Target value for the raw objective; stops when |
|
Stops after |
Example: max_iterations or real_time_limit will halt when the maximum number of iterations is reached or we have exceeded the maximum time.
Parameter schedules#
There are a number of already available schedules for parameters. Each of then calculate the parameter value from a progress value in the range [0, 1].
To simplify the math, the progress value is \(p\) and \(v\) is the parameter value, so that \(v(0)\) is the initial value and \(v(1)\) is the last value.
When using iteration-based values, we use \(v_i\) with \(i\) being the iteration number.
Schedule class |
Description |
Parameters |
|---|---|---|
Linearly interpolates the parameter between two values as:
\(v(p) = (1-p)v(0) + p\,v(1)\)
|
- init_value
- final_value
|
|
Uses a logistic curve to calculate the parameter:
\(v(p) = v(0) - \frac{v(1) - v(0)}{1 - e^{k(p - 0.5)}}\)
|
- init_value
- final_value
- k (10)
|
|
Uses a negative exponential curve to model the parameter, when iterative, ignores the final value:
when iterative is
False: \(v(p) = v(0) + (v(1) - v(0)) e^{-\alpha p}\)when iterative is
True: \(v_i = v_0 + (v_{i-1} - v_0) \alpha\) |
- init_value
- final_value (0)
- alpha (0.9)
- iterative (False)
|
|
Models the parameters as a cosine wave with:
\(v(p) = A\cos(2 \pi f \, p + \varphi) + v(0)\)
|
- offset (0)
- amplitude (1)
- frequency (1)
- phase (1)
|
|
Completely randomizes the parameter value within a range of values. Follows an uniform distribution: |
- init_value
- final_value
|
|
Chooses a value to assign for progress values below the threshold and another for values above it. |
- init_value
- final_value
- threshold (0.5)
|
|
Splits the range of 0 to 1 into \(N\) steps indicated by a dictionary of the form:
{0.1: 34, 0.2: 4, 0.3: 1, ...} |
- steps
|
|
Applies gaussian noise to a given parameter schedule.
|
- subschedule
- noise_level (1e-2)
|
|
Holds the previously seen parameter value for a number of iterations, ignoring the current evaluation of the parameter.
|
- subschedule
- iterations (100)
|
|
Schedule used by Simulated Annealing (
SA) for modelling the acceptance probabilityas a temperature that decreases exponentially.
\(T_i = T_0 + (T_i - T_0) \alpha\)
\(v_i = e^{-1/T_i}\)
|
- temperature_init (100)
- iterations (100)
- alpha (0.99)
|
Prepackaged Algorithms#
For ready‑to‑run algorithm wrappers, see the Simple API page.