metaheuristic_designer package

Subpackages

Submodules

metaheuristic_designer.algorithm module

Base class for the Algorithm module.

This module implements the main loop of the optimization algorithm using a search strategy.

exception TerminationException[source]

Bases: Exception

Custom exception to handle SIGTERM

class Algorithm(objfunc: ObjectiveFunc, search_strategy: SearchStrategy, name: str | None = None, stop_cond: str = 'real_time_limit', progress_metric: str | None = None, max_iterations: int = 1000, max_evaluations: int = 100000.0, real_time_limit: float = 60.0, cpu_time_limit: float = 60.0, objective_target: float = 1e-10, max_patience: int = 100, verbose_timer: float = 0.5, track_median: bool = False, track_worst: bool = False, track_full_objective: bool = False, track_full_population: bool = False, track_diversity: bool = False, checkpoint_file: str | None = None, checkpoint_time_frequency: float | None = None, checkpoint_iteration_frequency: float | None = None, stopping_condition: StoppingCondition | None = None, reporter: str | Reporter | None = None, history_tracker: HistoryTracker | None = None, checkpointer: Checkpointer | None = None, parallel: bool = False, threads: int = 8)[source]

Bases: object

Orchestrates a complete optimisation run.

An Algorithm combines a ObjectiveFunc with a SearchStrategy and manages the iteration loop, stopping conditions, reporting, history tracking, and checkpointing.

All runtime settings can be supplied as plain keyword arguments (e.g., max_iterations=200) or as pre-built objects (StoppingCondition, Reporter, etc.). The keyword-argument style is convenient for quick experiments; the object-based style gives finer control and reusability.

Parameters:
  • objfunc (ObjectiveFunc) – The objective function to optimise.

  • search_strategy (SearchStrategy) – Strategy that defines one iteration of the algorithm.

  • name (str, optional) – Display name for the algorithm (defaults to the strategy’s name).

  • stop_cond (str, optional) – Expression that defines the stopping condition (see StoppingCondition). Default "real_time_limit".

  • progress_metric (str, optional) – Token used to compute the 0-1 progress value for parameter schedules. Defaults to the same tokens as stop_cond.

  • max_iterations (int, optional) – Maximum number of iterations (default 1000).

  • max_evaluations (int, optional) – Maximum number of objective evaluations (default 1e5).

  • real_time_limit (float, optional) – Wall-clock time limit in seconds (default 60).

  • cpu_time_limit (float, optional) – CPU time limit in seconds (default 60).

  • objective_target (float, optional) – Target value for the raw objective (default 1e-10).

  • max_patience (int, optional) – Iterations without improvement before convergence stops (default 100).

  • verbose_timer (float, optional) – Interval in seconds between prints when using the default VerboseReporter (default 0.5).

  • track_diversity (track_median / track_worst / track_full_objective / track_full_population /) – Flags forwarded to the HistoryTracker when one is not supplied explicitly.

  • checkpoint_iteration_frequency (checkpoint_file / checkpoint_time_frequency /) – Arguments used to construct a Checkpointer when checkpointer is not given.

  • stopping_condition (StoppingCondition, optional) – Explicit stopping condition object.

  • reporter (str or Reporter, optional) – Reporter instance or name ("tqdm", "silent", "verbose").

  • history_tracker (HistoryTracker, optional) – Explicit history tracker.

  • checkpointer (Checkpointer, optional) – Explicit checkpointer.

  • parallel (bool, optional) – Whether to evaluate the population in parallel (currently reserved for future use).

  • threads (int, optional) – Number of threads for parallel evaluation (reserved).

property initializer: Initializer
property iterations: int
property evaluations: int
property patience_left: int
property progress: float
property population: Population
gather_parameters() dict[source]

Collect the current parameters of the underlying search strategy.

Returns:

A dictionary of parameter names and their current values.

Return type:

dict

best_solution() Tuple[Any, float][source]

Return the best decoded solution and its raw objective value.

Returns:

best_solution – A pair of the best individual with its objective value.

Return type:

Tuple[Any, float]

best_individual() Tuple[ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool], float][source]

Return the best genotype and its internal fitness value.

Returns:

best_solution – A pair of the best individual with its fitness.

Return type:

Tuple[VectorLike, float]

restart(restart_objfunc: bool = True)[source]

Reset internal counters and, optionally, the objective function.

Parameters:

restart_objfunc (bool, optional) – If True, also reset the objective function’s evaluation counter.

initialize(reset_objfunc: bool = True) Population[source]

Create and evaluate the initial population.

Parameters:

reset_objfunc (bool, optional) – Passed through to restart().

Returns:

The evaluated initial population.

Return type:

Population

step(population: Population | None = None) Population[source]

Execute one iteration of the optimisation loop.

The default implementation performs: parent selection -> perturbation -> evaluation -> survivor selection.

Parameters:

population (Population, optional) – The population at the start of the iteration. If not given, the currently stored population is used.

Returns:

The population after the iteration.

Return type:

Population

resume() Population[source]

Resume an interrupted run from the last checkpoint.

Returns:

The final population after the run completes.

Return type:

Population

optimize(resume: bool = False) Population[source]

Run the optimisation loop until a stopping condition is met.

Parameters:

resume (bool, optional) – If True, do not reset the algorithm state - continue from the current population and counters.

Returns:

The final population.

Return type:

Population

Raises:

KeyboardInterrupt, TerminationException – If the process is interrupted, a checkpoint is attempted before re-raising.

get_state(store_population: bool = False) dict[source]

Serialise the current algorithm state to a dictionary.

Parameters:

store_population (bool, optional) – If True, include the complete genotype matrix.

Returns:

Dictionary representation of the algorithm state.

Return type:

dict

store_state(file_name: str = 'dumped_state.json', readable: bool = False)[source]

Serialise the current algorithm state to a JSON file.

Parameters:
  • file_name (str, optional) – Destination path (default "dumped_state.json").

  • readable (bool, optional) – If True, produce indented JSON (larger but human readable).

to_pandas()[source]

Shorthand for self.history_tracker.to_pandas().

Returns:

Per-iteration summary of tracked metrics.

Return type:

pandas.DataFrame

to_pandas_full_objective()[source]

Shorthand for self.history_tracker.to_pandas_full_objective().

Returns:

Wide-format DataFrame with the full objective vector per generation.

Return type:

pandas.DataFrame

metaheuristic_designer.checkpointer module

Module for checkpointing and resuming optimisation runs.

class Checkpointer(checkpoint_file: str, iteration_frequency: int | None = None, time_frequency: float | None = None)[source]

Bases: object

Periodically save and restore the state of an optimisation run.

The checkpointer can be triggered by iteration count, elapsed wall-clock time, or both. It writes the entire Algorithm object to disk using cloudpickle, so that an interrupted run can be resumed later without losing progress.

Parameters:
  • checkpoint_file (str) – Path to the file where the checkpoint will be saved (e.g., "run.pkl").

  • iteration_frequency (int, optional) – Save a checkpoint every n iterations.

  • time_frequency (float, optional) – Save a checkpoint when at least this many seconds have elapsed since the last save.

Notes

At least one of iteration_frequency or time_frequency must be provided; otherwise the checkpointer does nothing and logs a warning.

restart()[source]

Reset the internal timer so that time-based checkpoints are measured from this moment onward.

checkpoint(algorithm: Algorithm)[source]

Evaluate whether a checkpoint should be saved, and perform the save if necessary.

Parameters:

algorithm (Algorithm) – The running algorithm instance.

save(algorithm: Algorithm)[source]

Serialize the algorithm to disk using cloudpickle.

A temporary file is written first and atomically moved to the final location, preventing corruption if the process crashes mid-write. The reporter, parallel flag, and the checkpointer itself are temporarily removed before pickling to avoid serialisation issues, and then restored.

Parameters:

algorithm (Algorithm) – The algorithm to save.

load(file_name: str | None = None, reporter: Reporter | str = 'silent', parallel: bool = False) Algorithm[source]

Restore a previously saved algorithm from a checkpoint file.

Parameters:
  • file_name (str, optional) – Path to the checkpoint file. If not provided, the path given at construction is used.

  • reporter (Reporter or str, optional) – Reporter to attach to the restored algorithm (a Reporter instance or a string like "tqdm", "silent"). Default is "silent".

  • parallel (bool, optional) – Whether parallel evaluation should be enabled after restoration. Default is False.

Returns:

The deserialized algorithm, ready to continue from where it was saved. Ensure you run the algorithm with .resume() so data is not lost.

Return type:

Algorithm

metaheuristic_designer.constraint_handler module

Base class for the Constraint Handler module.

This module implements ways to enforce constraints on the objective function.

class ConstraintHandler(encoding=None, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Abstract base for all constraint handlers.

A constraint handler can repair solutions (make them feasible) and/or compute a penalty that is subtracted from the objective value. Subclasses must implement at least one of these operations.

Parameters:
  • encoding (Encoding, optional) – An Encoding that will be used to extract the genotype before repair or penalty (default None).

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

abstract repair_solution(population_matrix: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Modifies the incoming solution so that it follows the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

fixed_solution – Modified version of the input solution that fits the problem’s constraints

Return type:

Any

abstract penalty(population_matrix: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Offset to the objective value for the solution corresponding to violations of the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

penalty – The amount of penalty to apply to the current solution.

Return type:

float

get_state()[source]
class ConstraintHandlerFromLambda(repair_solution_fn: Callable | None = None, penalty_fn: Callable | None = None, **kwargs)[source]

Bases: ConstraintHandler

Constraint handler built from plain callables.

At least one of repair_solution_fn or penalty_fn must be given.

Parameters:
  • repair_solution_fn (callable, optional) – A function (solution) -> repaired_solution.

  • penalty_fn (callable, optional) – A function (solution) -> penalty_value.

  • **kwargs – Keyword arguments forwarded to ConstraintHandler.

repair_solution(solution: Iterable) Iterable[source]

Modifies the incoming solution so that it follows the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

fixed_solution – Modified version of the input solution that fits the problem’s constraints

Return type:

Any

penalty(solution: Any) number | float | int[source]

Offset to the objective value for the solution corresponding to violations of the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

penalty – The amount of penalty to apply to the current solution.

Return type:

float

class NullConstraint(encoding=None, **kwargs)[source]

Bases: ConstraintHandler

Constraint handler that enforces no restrictions.

The penalty is always zero, and repairing returns the solution unchanged.

Parameters:
repair_solution(solution: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Modifies the incoming solution so that it follows the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

fixed_solution – Modified version of the input solution that fits the problem’s constraints

Return type:

Any

penalty(_solution: Any) number | float | int[source]

Offset to the objective value for the solution corresponding to violations of the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

penalty – The amount of penalty to apply to the current solution.

Return type:

float

class PenalizeConstraint(encoding=None, **kwargs)[source]

Bases: ConstraintHandler, ABC

Abstract handler that only computes penalties.

Repairing does nothing (returns a copy). Subclasses must override penalty().

Parameters:
repair_solution(solution: Iterable) Iterable[source]

Modifies the incoming solution so that it follows the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

fixed_solution – Modified version of the input solution that fits the problem’s constraints

Return type:

Any

class RepairConstraint(encoding=None, **kwargs)[source]

Bases: ConstraintHandler, ABC

Abstract handler that only repairs solutions.

The penalty is always zero. Subclasses must override repair_solution().

Parameters:
penalty(_solution: Iterable) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Offset to the objective value for the solution corresponding to violations of the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

penalty – The amount of penalty to apply to the current solution.

Return type:

float

metaheuristic_designer.encoding module

Base class for the Encoding module.

This module implements a way to have a different representation in the inner working of the algorithm and the result of the procedure.

class Encoding(decode_as_array: bool = False, name=None, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Translate between internal genotypes and problem-specific phenotypes.

An Encoding is responsible for converting a population matrix (the internal representation used by operators) into a collection of solutions that the objective function understands, and vice versa.

Parameters:
  • decode_as_array (bool, optional) – If True, decode() returns a NumPy array instead of an iterable of arbitrary objects. Default False.

  • name (str, optional) – Display name for this encoding.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

gather_params() dict[source]

Overridable thin wrapper around get_params

abstract encode(solutions: Iterable) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Encodes a list of solutions to our problem to an population matrix.

Parameters:

solutions (Iterable) – Solutions that should be encoded.

Returns:

population – Population array.

Return type:

ndarray

abstract decode(population: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) Iterable[source]

Decodes a population matrix into a list/array of solutions.

Parameters:

population (ndarray) – Population that should be decoded.

Returns:

solutions – List/array of solutions.

Return type:

Iterable

get_state() dict[source]
class DefaultEncoding(decode_as_array: bool = True)[source]

Bases: Encoding

Identity encoding - the internal genotype is used directly.

No transformation is applied; encode() and decode() return their arguments unchanged. This is the encoding used when no other is specified.

Parameters:

decode_as_array (bool, optional) – See Encoding. Default True.

encode(solution: Iterable) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Encodes a list of solutions to our problem to an population matrix.

Parameters:

solutions (Iterable) – Solutions that should be encoded.

Returns:

population – Population array.

Return type:

ndarray

decode(population: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) Iterable[source]

Decodes a population matrix into a list/array of solutions.

Parameters:

population (ndarray) – Population that should be decoded.

Returns:

solutions – List/array of solutions.

Return type:

Iterable

class EncodingFromLambda(encode_fn: Callable, decode_fn: Callable, **kwargs)[source]

Bases: Encoding

Encoding built from two callables.

Parameters:
  • encode_fn (callable) – (solutions) -> population_matrix.

  • decode_fn (callable) – (population_matrix) -> solutions.

  • decode_as_array (bool, optional) – See Encoding.

  • **kwargs – Forwarded to Encoding.

encode(solution: Iterable) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Encodes a list of solutions to our problem to an population matrix.

Parameters:

solutions (Iterable) – Solutions that should be encoded.

Returns:

population – Population array.

Return type:

ndarray

decode(population: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) Iterable[source]

Decodes a population matrix into a list/array of solutions.

Parameters:

population (ndarray) – Population that should be decoded.

Returns:

solutions – List/array of solutions.

Return type:

Iterable

metaheuristic_designer.history_tracker module

Module for recording per-generation metrics and exporting them as pandas DataFrames.

class HistoryTracker(track_best=True, track_median=False, track_worst=False, track_full_objective=False, track_full_population=False, track_parameters=False, track_diversity=False)[source]

Bases: object

Record per-generation metrics and export them as pandas DataFrames.

The tracker is called once per generation (via step()) and stores the requested statistics. After the run the data can be retrieved with to_pandas() (a summary of best, median, worst, diversity, and scheduled parameters) or to_pandas_full_objective() (the full objective vector of every individual at each generation).

Parameters:
  • track_best (bool, optional) – Record the best objective and solution (default True).

  • track_median (bool, optional) – Record the median objective (default False).

  • track_worst (bool, optional) – Record the worst objective (default False).

  • track_full_objective (bool, optional) – Store the complete objective vector of the population at every generation. Enables to_pandas_full_objective().

  • track_full_population (bool, optional) – Store the entire population (genotypes) at every generation. This can consume a lot of memory.

  • track_parameters (bool, optional) – Record the current value of all scheduled parameters (e.g., mutation strength, branch probability).

  • track_diversity (bool, optional) – Compute and store a simple diversity metric (average Euclidean distance from the centroid).

restart()[source]

Clear all recorded data.

Call this when an algorithm is reset to start a fresh run.

step(algorithm: Algorithm)[source]

Record metrics for the current generation.

Parameters:

algorithm (Algorithm) – The running algorithm from which the current population, fitness, objective, and parameters are extracted.

to_pandas()[source]

Return a DataFrame with per-generation summary metrics.

Columns include iteration, best_objective, median_objective, worst_objective, diversity, and one column per scheduled parameter. The DataFrame is intended for easy plotting with seaborn or matplotlib.

Return type:

pandas.DataFrame

to_pandas_full_objective()[source]

Return a wide-format DataFrame of all individual objective values.

Each column Individual_0, Individual_1, … holds the objective of one member of the population across generations. This is useful for boxplots or distribution plots of fitness.

Returns:

Empty DataFrame if track_full_objective was not enabled.

Return type:

pandas.DataFrame

get_state()[source]

Return a dictionary containing the recorded history.

Returns:

Keys include best_objective, best_solutions, etc. Only metrics that were enabled are present.

Return type:

dict

metaheuristic_designer.initializer module

Base class for the Initializer module.

This module implements functions to generate the initial population of the algorithm.

class Initializer(dimension: int, population_size: int = 1, encoding: Encoding | None = None, random_state: int | Generator | None = None)[source]

Bases: ABC

Abstract base for all population initializers.

An initializer creates the first generation of individuals. It must provide a way to generate a single random genotype vector (a 1-D NumPy array) via generate_random() and can optionally wrap it with a different definition of an individual via generate_individual().

Parameters:
  • dimension (int) – Length of the genotype vector.

  • population_size (int, optional) – Number of individuals to generate (default 1).

  • encoding (Encoding, optional) – Encoding that will be attached to every individual. Defaults to DefaultEncoding.

  • random_state (RNGLike, optional) – Random number generator.

abstract generate_random() ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Generate a single random genotype vector (1-D array).

Returns:

A newly generated genotype vector (1-D array).

Return type:

VectorLike

generate_individual() ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Generate a single individual.

By default simply delegates to generate_random(). Returns a newly generated individual (a 1-D array).

Override this method if your initializer needs to distinguish between a randomly initialize individual and a solution generated with another strategy (See SeedProbInitializer).

Returns:

A newly generated individual.

Return type:

Any

generate_population(objfunc: ObjectiveFunc, n_individuals: int | None = None) Population[source]

Create a fully formed population of n_individuals individuals.

Parameters:
  • objfunc (ObjectiveFunc) – Objective function that will be propagated to each individual.

  • n_individual (int, optional) – Number of individuals to generate

Returns:

generated_population – Newly generated population.

Return type:

Population

get_state() dict[source]

Return a minimal dictionary identifying this initializer.

Returns:

Dictionary with key "class_name".

Return type:

dict

class InitializerFromLambda(generator: Callable, dimension: int, pop_size: int = 1, encoding: Encoding | None = None, random_state: int | Generator | None = None)[source]

Bases: Initializer

Initializer that uses a user-provided function to generate individuals.

Parameters:
  • generator (callable) – A function (random_state) -> genotype that returns a single genotype vector.

  • dimension (int) – Length of the genotype vector.

  • pop_size (int, optional) – Number of individuals to generate (default 1).

  • encoding (Encoding, optional) – Encoding attached to every individual.

  • random_state (RNGLike, optional) – Random number generator.

generate_random() ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Generate a single random genotype vector (1-D array).

Returns:

A newly generated genotype vector (1-D array).

Return type:

VectorLike

metaheuristic_designer.objective_function module

Base class for the Objective Function module.

This module implements the objective function that will measure the quality of the solutions.

class ObjectiveFunc(dimension: int, lower_bound: number | float | int | ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | None = None, upper_bound: number | float | int | ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | None = None, constraint_handler: ConstraintHandler | None = None, mode: str = 'max', name: str = 'Some function', vectorized: bool = False, recalculate: bool = False, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Abstract objective function with built-in fitness conversion.

Subclasses must implement objective(), which returns the raw objective value. The base class automatically converts it to a fitness that is always maximised (flipping the sign for minimisation) and applies a penalty if a ConstraintHandler is present.

Parameters:
  • dimension (int) – Number of decision variables.

  • lower_bound (float or array-like, optional) – Lower bound(s) of the feasible region. When both bounds are given, a ClipBoundConstraint is added automatically.

  • upper_bound (float or array-like, optional) – Upper bound(s) of the feasible region.

  • constraint_handler (ConstraintHandler, optional) – Handler that can repair solutions and/or compute penalties.

  • mode (str, optional) – "max" or "min". The fitness is always maximised internally; the mode controls the sign conversion.

  • name (str, optional) – Human-readable name for this function.

  • vectorized (bool, optional) – If True, objective() receives the whole population at once and must return an array.

  • recalculate (bool, optional) – If True, every individual is re-evaluated even if its fitness has already been computed.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

fitness(population: Population, parallel: bool = False, threads: int = 8) VectorLike[source]

Evaluate fitness for the whole population.

The raw objective values are computed via objective(), penalties are subtracted, and the result (always maximised) is stored in population.fitness. Individuals that already have a valid fitness are skipped unless recalculate is set.

Parameters:
  • population (Population) – The population whose individuals will be evaluated.

  • parallel (bool, optional) – Reserved for future use, currently ignored.

  • threads (int, optional) – Reserved for future use, currently ignored.

Returns:

The new fitness values (also written in-place).

Return type:

ndarray

abstract objective(solution: Any) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | number | float | int[source]

Implementation of the objective function.

Parameters:

solution (Any) – The solution for which the fitness will be calculated.

Returns:

objective_value – Value of the objective function given a solution.

Return type:

VectorLike | ScalarLike

repair_solution(solution: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Transforms an invalid vector into one that satisfies the restrictions of the problem.

Parameters:

solution (MatrixLike) – A solution that could be violating the restrictions of the problem.

Returns:

repaired_solution – A modified version of the solution passed that satisfies the restrictions of the problem.

Return type:

MatrixLike

add_parameter_constraints(parameter_extending_encoding: ParameterExtendingEncoding, param_handlers: dict[str, ConstraintHandler])[source]

Attach extra constraint handlers for extended encodings (e.g., PSO).

Parameters:
  • parameter_extending_encoding (ParameterExtendingEncoding) – The encoding that splits the genotype into solution and auxiliary parameters.

  • param_handlers (dict) – Mapping from parameter names to ConstraintHandler instances.

restart()[source]

Reset the evaluation counter to zero.

get_state() dict[source]

Return a dictionary with the current configuration.

Returns:

Keys include class_name, name, constraint handler state, and all stored parameters.

Return type:

dict

class NullObjectiveFunc(**kwargs)[source]

Bases: ObjectiveFunc

Objective function that always returns zero.

Useful as a placeholder in tests or when the optimisation criterion is handled entirely by constraints.

Parameters:

**kwargs – Forwarded to ObjectiveFunc.

objective(_) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | number | float | int[source]

Implementation of the objective function.

Parameters:

solution (Any) – The solution for which the fitness will be calculated.

Returns:

objective_value – Value of the objective function given a solution.

Return type:

VectorLike | ScalarLike

class ObjectiveFromLambda(obj_func: Callable, dimension: int, lower_bound: number | float | int | ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | None = None, upper_bound: number | float | int | ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | None = None, constraint_handler: ConstraintHandler | None = None, mode: str = 'max', name: str | None = None, vectorized: bool = False, recalculate: bool = False, **kwargs)[source]

Bases: ObjectiveFunc

Objective function indicated by a function call.

Parameters:
  • obj_func (Callable) – Objective function as a callable object.

  • dimension (int) – The dimension of the vectors accepted by the objective function.

  • mode (str, optional) – Whether to maximize or minimize the function (using the string ‘max’ or ‘min’).

  • lower_bound (float, optional) – Lower limit restriction for the vectors.

  • upper_bound (float, optional) – Upper limit restriction for the vectors.

  • name (str, optional) – The name that will be displayed to represent this function.

objective(solution: Any) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | number | float | int[source]

Implementation of the objective function.

Parameters:

solution (Any) – The solution for which the fitness will be calculated.

Returns:

objective_value – Value of the objective function given a solution.

Return type:

VectorLike | ScalarLike

metaheuristic_designer.operator module

Base class for the Operator module.

This module implements procedures to modify the current solutions so that we explore the search space.

class Operator(name: str | None = None, encoding: Encoding | None = None, preserves_order: bool = False, random_state: int | Generator | None = None, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Abstract base for all perturbation operators.

An Operator modifies a population (typically by applying mutation, crossover, or a composite of several steps). Subclasses must implement evolve().

Parameters:
  • name (str, optional) – Display name for this operator.

  • encoding (Encoding, optional) – Post-processing applied to the genotype matrix after the operator runs. Defaults to DefaultEncoding.

  • preserves_order (bool, optional) – If True, the operator keeps individuals in the same order (useful for one-to-one survivor selection). Default False.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

gather_params()[source]

Return the current parameter dictionary (thin wrapper around get_params()).

abstract evolve(population: Population, initializer: Initializer | None = None) Population[source]

Evolves an population using a given strategy.

Parameters:
  • population (Population) – The population that will be used.

  • initializer (Initialize, optional) – The population initializer of the algorithm (used for randomly generating individuals).

Returns:

new_population – The modified population.

Return type:

Population

step(progress: float = 0)[source]

Updates the internal parameters.

get_state() dict[source]

Gets the current state of the algorithm as a dictionary.

Returns:

state – The complete state of the operator.

Return type:

dict

class NullOperator(name: str | None = None)[source]

Bases: Operator

Operator class that returns the individual without changes. Surprisingly useful.

Since it’s a no-op, it has the preserves_order flag set to True.

Parameters:

name (str, optional) – Name that is associated with the operator.

evolve(population: Population, *args) Population[source]

Evolves an population using a given strategy.

Parameters:
  • population (Population) – The population that will be used.

  • initializer (Initialize, optional) – The population initializer of the algorithm (used for randomly generating individuals).

Returns:

new_population – The modified population.

Return type:

Population

class OperatorFromLambda(operator_fn: Callable, name: str | None = None, encoding: Encoding | None = None, preserves_order: bool = False, random_state: int | Generator | None = None, **kwargs)[source]

Bases: Operator

Operator that wraps a user‑supplied function.

The function receives a Population, an Initializer, a random state, and any stored keyword arguments, and must return a modified Population.

Parameters:
  • operator_fn (callable) – A function (population, initializer, random_state, **kwargs) -> Population.

  • name (str, optional) – Display name (defaults to the function’s __name__).

  • encoding (Encoding, optional) – See Operator.

  • preserves_order (bool, optional) – See Operator.

  • random_state (RNGLike, optional) – See Operator.

  • **kwargs – Keyword arguments forwarded to Operator and also passed to operator_fn on each call.

evolve(population: Population, initializer: Initializer | None = None) Population[source]

Evolves an population using a given strategy.

Parameters:
  • population (Population) – The population that will be used.

  • initializer (Initialize, optional) – The population initializer of the algorithm (used for randomly generating individuals).

Returns:

new_population – The modified population.

Return type:

Population

metaheuristic_designer.parametrizable_mixin module

Module providing the ParametrizableMixin for managing schedulable parameters.

class ParametrizableMixin[source]

Bases: object

Mixin that turns raw keyword arguments into dynamic, schedulable parameters.

Any argument passed to store_kwargs() or update_kwargs() can be a plain value or a callable that receives the current progress (a float between 0 and 1) and returns the value to use. The current values are accessible via get_params() or the params property.

store_kwargs(progress: float = 0, **kwargs)[source]

Store keyword arguments and evaluate them at the given progress.

Parameters:
  • progress (float, optional) – Progress value forwarded to any callable parameters.

  • **kwargs – Parameter names and values (constants or callables).

step(progress: float)[source]

Re-evaluate all stored parameters at the current progress.

Parameters:

progress (float) – Current progress (0-1) used to evaluate callable parameters.

update_kwargs(progress: float = 0, **kwargs)[source]

Add or replace parameters and immediately evaluate them.

Parameters:
  • progress (float, optional) – Progress value forwarded to any callable parameters.

  • **kwargs – Parameter names and new values.

get_params() dict[source]

Return a copy of the current parameter dictionary.

Returns:

The evaluated (non-callable) parameter values.

Return type:

dict

property params

Access parameter values by attribute-style lookup.

Returns:

A helper object that reads from the current parameter dictionary.

Return type:

_ParamView

metaheuristic_designer.parent_selection_base module

Base class for the Parent Selection module.

class ParentSelection(name: str | None = None, amount: int | None = None, random_state: int | Generator | None = None, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Abstract base for all parent selection methods.

A parent selection chooses which individuals from the current population will be used to generate offspring. Subclasses must implement select(), which returns a new Population containing only the selected individuals.

Parameters:
  • name (str, optional) – Display name for this selection method.

  • amount (int, optional) – Default number of individuals to select. Can be overridden at call time.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

gather_params() dict[source]

Return the current parameter dictionary (thin wrapper around get_params()).

abstract select(population: Population, amount: int | None = None) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – List of selected individuals.

Return type:

Population

get_state() dict[source]

Return a dictionary with the selection method’s configuration.

Returns:

Keys include class_name, name, and all current parameters.

Return type:

dict

class NullParentSelection(name: str | None = 'Nothing', **kwargs)[source]

Bases: ParentSelection

Null parent selection, returns the whole population unchanged.

This is the identity element: no individuals are filtered out. Useful when the algorithm does not require a parent selection step (e.g., random search or certain evolution strategies).

Parameters:
  • name (str, optional) – Display name. Default "Nothing".

  • **kwargs – Keyword arguments forwarded to ParentSelection.

select(population: Population, amount: int | None = None) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – List of selected individuals.

Return type:

Population

class ParentSelectionFromLambda(selection_fn: Callable, name: str | None = None, amount: int | None = None, random_state: int | Generator | None = None, **kwargs)[source]

Bases: ParentSelection

Parent selection that wraps a user-supplied function.

The function receives the population, the number of individuals to select, a random state, and any stored keyword arguments, and must return an array of selected indices.

Parameters:
  • selection_fn (callable) – A function (population, amount, random_state, **kwargs) -> indices.

  • name (str, optional) – Display name (defaults to the function’s __name__).

  • amount (int, optional) – Default number of individuals to select.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Keyword arguments forwarded to ParentSelection.

select(population: Population, amount: int | None = None) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – List of selected individuals.

Return type:

Population

metaheuristic_designer.population module

Base class for the Population module.

This module implements a data structure to hold the collection of solutions we are considering.

class Population(objfunc: ObjectiveFunc, genotype_matrix: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool], encoding: Encoding | None = None)[source]

Bases: object

Container for a set of candidate solutions and their fitness.

A Population holds the genotype matrix, fitness and objective values, historical bests, and the current best individual. It is the central data structure passed between components of the optimisation loop.

Parameters:
  • objfunc (ObjectiveFunc) – The objective function that will evaluate the population.

  • genotype_matrix (ndarray) – 2-D array of shape (N, M) containing the genotypes.

  • encoding (Encoding, optional) – The encoding used to translate between genotype and phenotype. Defaults to DefaultEncoding.

best_individual() Tuple[ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool], float][source]

Return the best genotype and its maximised fitness value.

Returns:

  • best_genotype (MatrixLike) – The genotype vector of the best individual.

  • best_fitness (float) – The internal fitness (always maximised).

best_solution() Tuple[Any, float][source]

Return the best decoded solution and its raw objective value.

Returns:

  • solution (Any) – The decoded phenotype of the best individual.

  • objective (float) – The raw objective value.

update_genotype(genotype_source: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool] | Population) Population[source]

Replace the genotype matrix.

Parameters:

genotype_source (ndarray or Population) – New genotypes. If a Population is given, its genotype matrix is used.

Returns:

self, with updated genotypes and, if the size changed, re-initialised fitness and historical bests.

Return type:

Population

take_selection(selection_idx: ndarray[tuple[int, ...], integer] | ndarray[tuple[int, ...], uint8 | bool]) Population[source]

Takes a subset of the population given a mask.

Parameters:

selection_idx (ndarray) – An array of indices or a mask that indicate which individuals to take from the population.

Returns:

selected_population – A copy of the population containing only the chosen individuals.

Return type:

Population

apply_selection(selected_pop: Population, selection_idx: ndarray[tuple[int, ...], integer] | ndarray[tuple[int, ...], uint8 | bool]) Population[source]

Replaces the chosen individuals from the input population to the current population.

Parameters:
  • selected_pop (Population) – Population where to take the individuals that will replace the ones in the population.

  • selection_idx (ndarray) – An array of indices or a mask that indicate which individuals to take from the population.

Returns:

self

Return type:

Population

take_slice(mask: ndarray[tuple[int, ...], integer] | ndarray[tuple[int, ...], uint8 | bool]) Population[source]

Takes a subset of the components in the population vectors.

Parameters:

mask (ndarray) – An array of indices or a mask that indicate which components to take from each vector in the population.

Returns:

sliced_population – A copy of the population containing the masked individuals.

Return type:

Population

apply_slice(sliced_pop: Population, mask: ndarray[tuple[int, ...], integer] | ndarray[tuple[int, ...], uint8 | bool]) Population[source]

Apply the values of the population to a subset of the components of the population vectors.

Parameters:
  • sliced_pop (Population) – Population where to take the individuals from which we will take the components that will replace the ones in the current population.

  • mask (ndarray) – An array of indices or a mask that indicate which components to take from each vector in the population.

Returns:

self

Return type:

Population

static join_populations(population1: Population, population2: Population) Population[source]

Concatenate two populations into a new one.

Parameters:
Returns:

A new population containing all individuals from both inputs.

Return type:

Population

join(other_population: Population) Population[source]

Adds to the current population the individuals of the input population.

Parameters:

other_population (Population) – Population that will be concatenated with the current one.

Returns:

joined_populations – A population containing both the individuals from the current population and the ones from the input population.

Return type:

Population

sort_population() Population[source]

Sorts the individuals by fitness.

Returns:

self

Return type:

Population

update_best_from_parents(parents: Population) Population[source]

Update the best solution if a better one exists in parents.

Parameters:

parents (Population) – Population whose best individual may improve the current one.

Returns:

self, with possibly updated best, best_fitness, and best_objective.

Return type:

Population

step(_progress: float = 0) Population[source]

Updates the best solution in the population.

Returns:

self

Return type:

Population

repeat(amount: int = 2) Population[source]

Duplicates the individuals of the population.

Parameters:

amount (int, optional) – The amount of times to repeat the individuals in the population.

Returns:

repeated_population

Return type:

Population

calculate_fitness(parallel: bool = False, threads: int = 8) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Calculates the fitness of the individual if it has not been calculated before

Parameters:
  • parallel (bool, optional) – Whether to evaluate the individuals in the population in parallel.

  • threads (int, optional) – Number of processes to use at once if calculating the fitness in parallel.

Returns:

fitness

Return type:

ndarray

repair_solutions() Population[source]

Repairs the solutions in the population.

Returns:

self

Return type:

Population

decode(encoding: Encoding | None = None) Iterable[source]

Return the population passed through the decoding function defined in the encoding.

Returns:

decoded_population

Return type:

Any

decode_params(encoding: Encoding | None = None) Iterable[source]

Decode the auxiliary parameters stored in the genotype.

Only works with ParameterExtendingEncoding.

Parameters:

encoding (Encoding, optional) – Encoding to use; defaults to self.encoding.

Returns:

Dictionary of parameter arrays, or None if the encoding does not support extended parameters.

Return type:

dict or None

encode(encoding: Encoding | None = None) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Encode the current population using the given encoding.

Parameters:

encoding (Encoding, optional) – Encoding to use; defaults to self.encoding.

Returns:

The encoded genotype matrix.

Return type:

MatrixLike

get_state() dict[source]

Return a dictionary with the current population state.

Returns:

Keys include genotype_matrix, fitness, objective, historical bests, and the best individual.

Return type:

dict

debug_repr(max_solutions: int = 5, max_vars: int = 5) str[source]

Return a compact string representation for debugging.

Parameters:
  • max_solutions (int, optional) – Maximum number of rows to include in the preview.

  • max_vars (int, optional) – Maximum number of columns to include in the preview.

Return type:

str

metaheuristic_designer.reporter module

Module defining the abstract reporter interface for algorithm progress output.

class Reporter[source]

Bases: ABC

Abstract interface for progress reporters.

A reporter is notified at three key moments of an optimisation run: initialisation, after each generation, and at completion. Implementations can display progress bars, log messages, update dashboards, etc.

abstract log_init(algorithm: Algorithm)[source]

Called once, before the main optimisation loop starts.

Parameters:

algorithm (Algorithm) – The algorithm that is about to run.

abstract log_step(algorithm: Algorithm)[source]

Called after each generation.

Parameters:

algorithm (Algorithm) – The running algorithm, with up-to-date population, iteration count, and best solution.

abstract log_end(algorithm: Algorithm)[source]

Called once, after the optimisation loop finishes.

Parameters:

algorithm (Algorithm) – The algorithm that has just finished.

metaheuristic_designer.schedulable_parameter module

Module for schedule-dependent parameters whose value changes with progress.

class SchedulableParameter(random_state: int | Generator | None = None)[source]

Bases: ABC

Abstract base for parameters that depend on the optimisation progress.

A schedulable parameter is a callable that receives a progress value between 0 and 1 and returns the parameter’s value at that point. Subclasses implement evaluate().

Parameters:

random_state (RNGLike, optional) – Random number generator, made available for subclasses that need stochastic schedules.

abstract evaluate(progress: float) Any[source]

Return the parameter value at the given progress.

Parameters:

progress (float) – Current progress, a number between 0 (start) and 1 (end).

Returns:

The parameter value at this stage of the optimisation.

Return type:

Any

Notes

The return value is not restricted to numbers. You can return: * a float (e.g., a linearly decaying mutation strength), * an int (e.g., a discrete number of mutated components), * a bool (e.g., switching on/off a feature after a threshold), * a string (e.g., switching between strategies), or * any other object that the consuming component expects.

This makes schedules suitable for changing discrete algorithm choices as well as continuous numerical parameters.

class ParameterFromLambda(schedule_fn: Callable, random_state: int | Generator | None = None)[source]

Bases: SchedulableParameter

Schedulable parameter that wraps a user-supplied function.

Parameters:
  • schedule_fn (callable) – A function (progress) -> value that defines the schedule.

  • random_state (RNGLike, optional) – Random number generator (passed through to the base class).

evaluate(progress: float) Any[source]

Return the parameter value at the given progress.

Parameters:

progress (float) – Current progress, a number between 0 (start) and 1 (end).

Returns:

The parameter value at this stage of the optimisation.

Return type:

Any

Notes

The return value is not restricted to numbers. You can return: * a float (e.g., a linearly decaying mutation strength), * an int (e.g., a discrete number of mutated components), * a bool (e.g., switching on/off a feature after a threshold), * a string (e.g., switching between strategies), or * any other object that the consuming component expects.

This makes schedules suitable for changing discrete algorithm choices as well as continuous numerical parameters.

metaheuristic_designer.search_strategy module

Base class for the Search strategy module.

This module implements the procedure applied in each iteration of the algorithm.

class SearchStrategy(initializer: Initializer, operator: Operator | None = None, parent_sel: ParentSelection | None = None, survivor_sel: SurvivorSelection | None = None, name: str = 'some strategy', random_state: int | Generator | None = None, **kwargs)[source]

Bases: ParametrizableMixin

Orchestrates one iteration of an optimisation loop.

A search strategy holds together an Initializer, an Operator, a ParentSelection, and a SurvivorSelection. Together they define how the population is created, perturbed, and pruned each generation. Subclasses can override any step to implement algorithm-specific logic.

Parameters:
  • initializer (Initializer) – Creates the starting population.

  • operator (Operator, optional) – The perturbation operator (mutation, crossover, …). Defaults to NullOperator.

  • parent_sel (ParentSelection, optional) – Selects which individuals are used to generate offspring. Defaults to NullParentSelection.

  • survivor_sel (SurvivorSelection, optional) – Selects which individuals survive to the next generation. Defaults to NullSurvivorSelection.

  • name (str, optional) – Display name used in reports.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

property population_size: int

Gets the amount of individuals in the population.

gather_parameters()[source]

Collect the current parameters from all sub-components.

Returns:

A flat dictionary with dotted keys like "operator.F", "parent_sel.amount", etc.

Return type:

dict

best_solution() Tuple[Any, float][source]

Returns the best solution found by the search strategy and its fitness.

Returns:

best_solution – A pair of the best individual with its fitness.

Return type:

Tuple[Any, float]

initialize(objfunc: ObjectiveFunc) Population[source]

Initializes the optimization search strategy.

Parameters:

objfunc (ObjectiveFunc) – Objective function to be optimized.

Returns:

population – The initial population to be used in the algoritm.

Return type:

Population

evaluate_population(population: Population, parallel: bool = False, threads: int = 8) Population[source]

Calculates the fitness of the individuals on the population.

Parameters:
  • population (Population)

  • parallel (bool, optional) – Whether to evaluate the individuals in the population in parallel.

  • threads (int, optional) – Number of processes to use at once if calculating the fitness in parallel.

Returns:

population – The population with the fitness values recorded.

Return type:

Population

select_parents(population: Population, amount: int | None = None) Population[source]

Selects the individuals that will be perturbed in this generation to generate the offspring.

Parameters:

population (Population) – The current population of the search strategy.

Returns:

parents – A pair of the list of individuals considered as parents and their position in the original population.

Return type:

Population

perturb(parents: Population, **kwargs) Population[source]

Applies operators to the population to get the next generation of individuals.

Parameters:

parents (Population) – The current parents that will be used in the search strategy.

Returns:

offspring – The list of individuals modified by the operators of the search strategy.

Return type:

Population

repair_population(population: Population) Population[source]

Repairs the individuals in the population to make them fulfill the problem’s restrictions.

Parameters:

population (Population) – The population to be repaired

Returns:

repaired_population – The population of repaired individuals

Return type:

Population

select_individuals(population: Population, offspring: Population, **kwargs) Population[source]

Selects the individuals that will pass to the next generation.

Parameters:
  • population (Population) – The current population of the search strategy.

  • offspring (Population) – The list of individuals modified by the operators of the search strategy.

Returns:

offspring – The list of individuals selected for the next generation.

Return type:

Population

step(progress: float)[source]

Update internal parameters and forward progress to sub-components.

Parameters:

progress (float) – Current progress of the algorithm (0-1).

get_state(store_population: bool = False) dict[source]

Gets the current state of the search strategy as a dictionary.

Parameters:

show_population (bool, optional) – Save the state of the current population.

Returns:

state – The complete state of the search strategy.

Return type:

dict

extra_step_info()[source]

Hook called after each generation (intended for subclasses).

extra_report()[source]

Hook called at the end of the optimisation (intended for subclasses).

class SearchStrategyFromLambda(initializer: Callable | Initializer, operator: Callable | Operator | None = None, parent_sel: Callable | ParentSelection | None = None, survivor_sel: Callable | SurvivorSelection | None = None, name: str = 'Strategy from lambda', encoding: Encoding | None = None, encode_fn: Callable | None = None, decode_fn: Callable | None = None, parent_selection_amount: int | None = None, pop_size: int = 100, random_state: int | Generator | None = None, **kwargs)[source]

Bases: SearchStrategy

Strategy whose components can be plain functions.

Accepts each component as either a properly constructed object or a callable; if a callable is provided it is automatically wrapped with the appropriate *FromLambda class. This is the simplest way to build a custom strategy in one go.

Parameters:
  • initializer (callable or Initializer) – Function (random_state) -> genotype, or an initializer instance.

  • operator (callable or Operator, optional) – Function (population, initializer, random_state, **kwargs) -> Population, or an operator instance.

  • parent_sel (callable or ParentSelection, optional) – Function (population, amount, random_state, **kwargs) -> indices, or a selection instance.

  • survivor_sel (callable or SurvivorSelection, optional) – Function (parent_fitness, offspring_fitness, random_state, **kwargs) -> indices, or a selection instance.

  • name (str, optional) – Display name (default "Strategy from lambda").

  • encoding (Encoding, optional) – Encoding that wraps encode/decode; overridden by encode_fn/decode_fn if both are given.

  • decode_fn (encode_fn /) – Standalone encode/decode functions.

  • parent_selection_amount (int, optional) – Amount of parents to select (used only when wrapping a callable parent_sel).

  • pop_size (int, optional) – Population size (used only when wrapping a callable initializer). Default 100.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Forwarded to SearchStrategy.

metaheuristic_designer.stopping_condition module

Module for algorithm stopping conditions and progress metric evaluation.

class StoppingCondition(condition_str: str, progress_metric_str: str | None = None, max_iterations: int | None = None, max_evaluations: int | None = None, real_time_limit: float | None = None, cpu_time_limit: float | None = None, objective_target: float | None = None, max_patience: int | None = None, optimization_mode: str = 'max')[source]

Bases: object

Encapsulate the logic that decides when an optimisation run should end.

A stopping condition is built from a logical expression that combines tokens with and, or and parentheses. Each token has a corresponding numeric limit. The same expression (or a separate one) can be used to compute a progress value between 0 and 1 for parameter schedules.

Parameters:
  • condition_str (str) – Logical expression defining when to stop (e.g. "max_iterations or real_time_limit").

  • progress_metric_str (str, optional) – Logical expression defining how to compute the 0-1 progress value. Defaults to condition_str.

  • max_iterations (int, optional) – Maximum number of generations.

  • max_evaluations (int, optional) – Maximum number of objective function evaluations.

  • real_time_limit (float, optional) – Wall-clock time limit in seconds.

  • cpu_time_limit (float, optional) – CPU time limit in seconds.

  • objective_target (float, optional) – Target value for the raw objective.

  • max_patience (int, optional) – Consecutive iterations without improvement before "convergence" triggers.

  • optimization_mode (str, optional) – "max" or "min", how the objective target and convergence are evaluated.

condition_str: str
progress_metric_str: str | None = None
max_iterations: int = None
max_evaluations: int = None
real_time_limit: float = None
cpu_time_limit: float = None
objective_target: float = None
max_patience: int = None
optimization_mode: str = 'max'
restart()[source]

Reset all counters and timers for a fresh run.

step(current_population: Population)[source]

Advance internal counters after one generation.

Parameters:

current_population (Population) – The population at the end of the current generation. Its best objective is used to update convergence tracking.

is_finished(finished: bool = False) bool[source]

Given the state of the algorithm, returns wether we have finished or not.

Parameters:
  • real_time_start (float) – The time in seconds that passed since the algorithm was executed.

  • cpu_time_start (float) – The time in seconds that the CPU has executed code in this algorithm.

Returns:

has_stopped – Whether the algorithm has reached its end

Return type:

bool

get_progress() float[source]

Compute the current progress (0-1) according to the progress metric.

Parameters:
  • gen (int) – The number of generations that has passed.

  • real_time_start (float) – The time in seconds that passed since the algorithm was executed.

  • cpu_time_start (float) – The time in seconds that the CPU has executed code in this algorithm.

Returns:

A value between 0 (start) and 1 (finished).

Return type:

float

get_state()[source]

Return a dictionary with the current state of the stopping condition.

Returns:

Keys include iterations, evaluations, times, and configuration limits.

Return type:

dict

parse_stopping_cond(condition_str: str) List[str | List][source]

This function parses an expression of the form “neval or cpu_time” into a tree structure so that it can be further processed.

Parameters:

condition_str (str) – The string to be parsed.

Returns:

token_list – The list of tokens representing the original string.

Return type:

List[str | List]

process_condition(cond_parsed: List[str | List], neval: int, ngen: int, real_time: float, cpu_time: float, target: float, patience: int) bool[source]

This function receives as an input an expression for the stopping condition and the truth variable of the possible stopping conditions and returns wether to stop or not.

Parameters:
  • cond_parsed (List[str | List]) – The list of tokens representing the parsed stopping condition.

  • neval (int) – Number of function evaluations done.

  • ngen (int) – Number of iterations done by the algorithm

  • real_time (float) – Time since the start of the algorithm.

  • cpu_time (float) – Time dedicated by the CPU to optimizing our function.

  • target (float) – Fitness target.

  • patience (int) – Number of time the algorithm has reached the same fitness value in a row.

Returns:

has_stopped – Whether the algorithm has reached its end

Return type:

bool

process_progress(cond_parsed: List[str | List], neval: int, ngen: int, real_time: float, cpu_time: float, target: float, patience: int) float[source]

This function receives as an input an expression for the stopping condition and the truth variable of the possible stopping conditions and returns wether to stop or not.

Parameters:
  • cond_parsed (List[str | List]) – The list of tokens representing the parsed stopping condition.

  • neval (int) – Number of function evaluations done.

  • ngen (int) – Number of iterations done by the algorithm

  • real_time (float) – Time since the start of the algorithm.

  • cpu_time (float) – Time dedicated by the CPU to optimizing our function.

  • target (float) – Fitness target.

  • patience (int) – Number of time the algorithm has reached the same fitness value in a row.

Returns:

has_stopped – Indicator of how close it the algorithm to finishing, 1 means the algorithm should be stopped.

Return type:

bool

metaheuristic_designer.survivor_selection_base module

Base class for the Survivor Selection module.

class SurvivorSelection(name: str | None = None, preserves_order: bool = False, random_state: int | Generator | None = None, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Abstract base for all survivor selection methods.

A survivor selection decides which individuals from the current population and the newly generated offspring will form the next generation. Subclasses must implement select().

Parameters:
  • name (str, optional) – Display name for this selection method.

  • preserves_order (bool, optional) – If True, the order of individuals is kept (useful for one-to-one competition schemes). Default False.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

gather_params()[source]

Return the current parameter dictionary (thin wrapper around get_params()).

abstract select(population: Population, offspring: Population) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – Population containing only the selected survivors.

Return type:

Population

get_state() dict[source]

Return a dictionary with the selection method’s configuration.

Returns:

Keys include class_name, name, and all current parameters.

Return type:

dict

class NullSurvivorSelection(name: str | None = 'Nothing', **kwargs)[source]

Bases: SurvivorSelection

Null survivor selection, offspring replace parents entirely.

This is the identity element for generational replacement: all parents are discarded and all offspring survive. The population size must be maintained by the offspring.

Parameters:
  • name (str, optional) – Display name. Default "Nothing".

  • **kwargs – Keyword arguments forwarded to SurvivorSelection.

select(population: Population, offspring: Population) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – Population containing only the selected survivors.

Return type:

Population

class SurvivorSelectionFromLambda(selection_fn: Callable, name: str | None = None, preserves_order: bool = False, random_state: int | Generator | None = None, **kwargs)[source]

Bases: SurvivorSelection

Survivor selection that wraps a user-supplied function.

The function receives the parent population, the offspring population, a random state, and any stored keyword arguments, and must return an array of indices into the concatenated pool.

Parameters:
  • selection_fn (callable) – A function (parents, offspring, random_state, **kwargs) -> indices.

  • name (str, optional) – Display name (defaults to the function’s __name__).

  • preserves_order (bool, optional) – See SurvivorSelection.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Keyword arguments forwarded to SurvivorSelection.

select(population: Population, offspring: Population) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – Population containing only the selected survivors.

Return type:

Population

metaheuristic_designer.utils module

Utility functions, type aliases, and a JSON encoder used across the library.

class NumpyEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]

Bases: JSONEncoder

JSON encoder that can serialize NumPy scalars, arrays, and Enums.

Use this encoder with json.dumps or json.dump when your data structure contains NumPy integers, floats, or arrays, or when you need to serialize Enum values as their string names.

default(o)[source]

Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this:

def default(self, o):
    try:
        iterable = iter(o)
    except TypeError:
        pass
    else:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return JSONEncoder.default(self, o)
check_random_state(seed: int | Generator | None) Generator[source]

Turn seed into an np.random.Generator instance.

Original implementation adapted from: https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/utils/validation.py BSD 3-Clause License, Copyright (c) 2007-2025 The scikit-learn developers.

Parameters:

seed (None, int or instance of Generator) – If seed is None, return the Generator singleton used by np.random. If seed is an int, return a new Generator instance seeded with seed. If seed is already a Generator instance, return it. Otherwise raise ValueError.

Returns:

The random state object based on seed parameter.

Return type:

numpy:numpy.random.Generator

per_individual(func)[source]

Decorator that applies a function to each row of a 2-D array.

The wrapped function receives a single row (a 1-D array) and any keyword arguments, and must return a 1-D array of the same length. The decorator loops over rows and stacks the results back into a 2-D array.

Parameters:

func (callable) – A function (row, **kwargs) -> 1-D array.

Returns:

A function that accepts a 2-D matrix and returns a 2-D array.

Return type:

callable

per_individual_list(func)[source]

Decorator that applies a function to each element of a list.

The wrapped function receives a single element and any keyword arguments, and returns a transformed element. The decorator loops over the list and returns a new list of the results.

Parameters:

func (callable) – A function (value, **kwargs) -> Any.

Returns:

A function that accepts a list and returns a list.

Return type:

callable

Module contents

Metaheuristic-designer: a modular framework for building, testing, and analysing population-based optimisation algorithms.

The library provides composable building blocks (initializers, encodings, operators, selection methods, and search strategies) that can be assembled into classical and custom metaheuristics with full reproducibility.

check_random_state(seed: int | Generator | None) Generator[source]

Turn seed into an np.random.Generator instance.

Original implementation adapted from: https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/utils/validation.py BSD 3-Clause License, Copyright (c) 2007-2025 The scikit-learn developers.

Parameters:

seed (None, int or instance of Generator) – If seed is None, return the Generator singleton used by np.random. If seed is an int, return a new Generator instance seeded with seed. If seed is already a Generator instance, return it. Otherwise raise ValueError.

Returns:

The random state object based on seed parameter.

Return type:

numpy:numpy.random.Generator

class ObjectiveFunc(dimension: int, lower_bound: number | float | int | ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | None = None, upper_bound: number | float | int | ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | None = None, constraint_handler: ConstraintHandler | None = None, mode: str = 'max', name: str = 'Some function', vectorized: bool = False, recalculate: bool = False, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Abstract objective function with built-in fitness conversion.

Subclasses must implement objective(), which returns the raw objective value. The base class automatically converts it to a fitness that is always maximised (flipping the sign for minimisation) and applies a penalty if a ConstraintHandler is present.

Parameters:
  • dimension (int) – Number of decision variables.

  • lower_bound (float or array-like, optional) – Lower bound(s) of the feasible region. When both bounds are given, a ClipBoundConstraint is added automatically.

  • upper_bound (float or array-like, optional) – Upper bound(s) of the feasible region.

  • constraint_handler (ConstraintHandler, optional) – Handler that can repair solutions and/or compute penalties.

  • mode (str, optional) – "max" or "min". The fitness is always maximised internally; the mode controls the sign conversion.

  • name (str, optional) – Human-readable name for this function.

  • vectorized (bool, optional) – If True, objective() receives the whole population at once and must return an array.

  • recalculate (bool, optional) – If True, every individual is re-evaluated even if its fitness has already been computed.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

fitness(population: Population, parallel: bool = False, threads: int = 8) VectorLike[source]

Evaluate fitness for the whole population.

The raw objective values are computed via objective(), penalties are subtracted, and the result (always maximised) is stored in population.fitness. Individuals that already have a valid fitness are skipped unless recalculate is set.

Parameters:
  • population (Population) – The population whose individuals will be evaluated.

  • parallel (bool, optional) – Reserved for future use, currently ignored.

  • threads (int, optional) – Reserved for future use, currently ignored.

Returns:

The new fitness values (also written in-place).

Return type:

ndarray

abstract objective(solution: Any) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | number | float | int[source]

Implementation of the objective function.

Parameters:

solution (Any) – The solution for which the fitness will be calculated.

Returns:

objective_value – Value of the objective function given a solution.

Return type:

VectorLike | ScalarLike

repair_solution(solution: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Transforms an invalid vector into one that satisfies the restrictions of the problem.

Parameters:

solution (MatrixLike) – A solution that could be violating the restrictions of the problem.

Returns:

repaired_solution – A modified version of the solution passed that satisfies the restrictions of the problem.

Return type:

MatrixLike

add_parameter_constraints(parameter_extending_encoding: ParameterExtendingEncoding, param_handlers: dict[str, ConstraintHandler])[source]

Attach extra constraint handlers for extended encodings (e.g., PSO).

Parameters:
  • parameter_extending_encoding (ParameterExtendingEncoding) – The encoding that splits the genotype into solution and auxiliary parameters.

  • param_handlers (dict) – Mapping from parameter names to ConstraintHandler instances.

restart()[source]

Reset the evaluation counter to zero.

get_state() dict[source]

Return a dictionary with the current configuration.

Returns:

Keys include class_name, name, constraint handler state, and all stored parameters.

Return type:

dict

class NullObjectiveFunc(**kwargs)[source]

Bases: ObjectiveFunc

Objective function that always returns zero.

Useful as a placeholder in tests or when the optimisation criterion is handled entirely by constraints.

Parameters:

**kwargs – Forwarded to ObjectiveFunc.

objective(_) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | number | float | int[source]

Implementation of the objective function.

Parameters:

solution (Any) – The solution for which the fitness will be calculated.

Returns:

objective_value – Value of the objective function given a solution.

Return type:

VectorLike | ScalarLike

class ObjectiveFromLambda(obj_func: Callable, dimension: int, lower_bound: number | float | int | ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | None = None, upper_bound: number | float | int | ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | None = None, constraint_handler: ConstraintHandler | None = None, mode: str = 'max', name: str | None = None, vectorized: bool = False, recalculate: bool = False, **kwargs)[source]

Bases: ObjectiveFunc

Objective function indicated by a function call.

Parameters:
  • obj_func (Callable) – Objective function as a callable object.

  • dimension (int) – The dimension of the vectors accepted by the objective function.

  • mode (str, optional) – Whether to maximize or minimize the function (using the string ‘max’ or ‘min’).

  • lower_bound (float, optional) – Lower limit restriction for the vectors.

  • upper_bound (float, optional) – Upper limit restriction for the vectors.

  • name (str, optional) – The name that will be displayed to represent this function.

objective(solution: Any) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool] | number | float | int[source]

Implementation of the objective function.

Parameters:

solution (Any) – The solution for which the fitness will be calculated.

Returns:

objective_value – Value of the objective function given a solution.

Return type:

VectorLike | ScalarLike

class ConstraintHandler(encoding=None, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Abstract base for all constraint handlers.

A constraint handler can repair solutions (make them feasible) and/or compute a penalty that is subtracted from the objective value. Subclasses must implement at least one of these operations.

Parameters:
  • encoding (Encoding, optional) – An Encoding that will be used to extract the genotype before repair or penalty (default None).

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

abstract repair_solution(population_matrix: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Modifies the incoming solution so that it follows the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

fixed_solution – Modified version of the input solution that fits the problem’s constraints

Return type:

Any

abstract penalty(population_matrix: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Offset to the objective value for the solution corresponding to violations of the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

penalty – The amount of penalty to apply to the current solution.

Return type:

float

get_state()[source]
class ConstraintHandlerFromLambda(repair_solution_fn: Callable | None = None, penalty_fn: Callable | None = None, **kwargs)[source]

Bases: ConstraintHandler

Constraint handler built from plain callables.

At least one of repair_solution_fn or penalty_fn must be given.

Parameters:
  • repair_solution_fn (callable, optional) – A function (solution) -> repaired_solution.

  • penalty_fn (callable, optional) – A function (solution) -> penalty_value.

  • **kwargs – Keyword arguments forwarded to ConstraintHandler.

repair_solution(solution: Iterable) Iterable[source]

Modifies the incoming solution so that it follows the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

fixed_solution – Modified version of the input solution that fits the problem’s constraints

Return type:

Any

penalty(solution: Any) number | float | int[source]

Offset to the objective value for the solution corresponding to violations of the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

penalty – The amount of penalty to apply to the current solution.

Return type:

float

class NullConstraint(encoding=None, **kwargs)[source]

Bases: ConstraintHandler

Constraint handler that enforces no restrictions.

The penalty is always zero, and repairing returns the solution unchanged.

Parameters:
repair_solution(solution: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Modifies the incoming solution so that it follows the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

fixed_solution – Modified version of the input solution that fits the problem’s constraints

Return type:

Any

penalty(_solution: Any) number | float | int[source]

Offset to the objective value for the solution corresponding to violations of the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

penalty – The amount of penalty to apply to the current solution.

Return type:

float

class PenalizeConstraint(encoding=None, **kwargs)[source]

Bases: ConstraintHandler, ABC

Abstract handler that only computes penalties.

Repairing does nothing (returns a copy). Subclasses must override penalty().

Parameters:
repair_solution(solution: Iterable) Iterable[source]

Modifies the incoming solution so that it follows the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

fixed_solution – Modified version of the input solution that fits the problem’s constraints

Return type:

Any

class RepairConstraint(encoding=None, **kwargs)[source]

Bases: ConstraintHandler, ABC

Abstract handler that only repairs solutions.

The penalty is always zero. Subclasses must override repair_solution().

Parameters:
penalty(_solution: Iterable) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Offset to the objective value for the solution corresponding to violations of the problem’s constraints.

Parameters:

solution (Any) – The input solution.

Returns:

penalty – The amount of penalty to apply to the current solution.

Return type:

float

class ParametrizableMixin[source]

Bases: object

Mixin that turns raw keyword arguments into dynamic, schedulable parameters.

Any argument passed to store_kwargs() or update_kwargs() can be a plain value or a callable that receives the current progress (a float between 0 and 1) and returns the value to use. The current values are accessible via get_params() or the params property.

store_kwargs(progress: float = 0, **kwargs)[source]

Store keyword arguments and evaluate them at the given progress.

Parameters:
  • progress (float, optional) – Progress value forwarded to any callable parameters.

  • **kwargs – Parameter names and values (constants or callables).

step(progress: float)[source]

Re-evaluate all stored parameters at the current progress.

Parameters:

progress (float) – Current progress (0-1) used to evaluate callable parameters.

update_kwargs(progress: float = 0, **kwargs)[source]

Add or replace parameters and immediately evaluate them.

Parameters:
  • progress (float, optional) – Progress value forwarded to any callable parameters.

  • **kwargs – Parameter names and new values.

get_params() dict[source]

Return a copy of the current parameter dictionary.

Returns:

The evaluated (non-callable) parameter values.

Return type:

dict

property params

Access parameter values by attribute-style lookup.

Returns:

A helper object that reads from the current parameter dictionary.

Return type:

_ParamView

class SchedulableParameter(random_state: int | Generator | None = None)[source]

Bases: ABC

Abstract base for parameters that depend on the optimisation progress.

A schedulable parameter is a callable that receives a progress value between 0 and 1 and returns the parameter’s value at that point. Subclasses implement evaluate().

Parameters:

random_state (RNGLike, optional) – Random number generator, made available for subclasses that need stochastic schedules.

abstract evaluate(progress: float) Any[source]

Return the parameter value at the given progress.

Parameters:

progress (float) – Current progress, a number between 0 (start) and 1 (end).

Returns:

The parameter value at this stage of the optimisation.

Return type:

Any

Notes

The return value is not restricted to numbers. You can return: * a float (e.g., a linearly decaying mutation strength), * an int (e.g., a discrete number of mutated components), * a bool (e.g., switching on/off a feature after a threshold), * a string (e.g., switching between strategies), or * any other object that the consuming component expects.

This makes schedules suitable for changing discrete algorithm choices as well as continuous numerical parameters.

class ParameterFromLambda(schedule_fn: Callable, random_state: int | Generator | None = None)[source]

Bases: SchedulableParameter

Schedulable parameter that wraps a user-supplied function.

Parameters:
  • schedule_fn (callable) – A function (progress) -> value that defines the schedule.

  • random_state (RNGLike, optional) – Random number generator (passed through to the base class).

evaluate(progress: float) Any[source]

Return the parameter value at the given progress.

Parameters:

progress (float) – Current progress, a number between 0 (start) and 1 (end).

Returns:

The parameter value at this stage of the optimisation.

Return type:

Any

Notes

The return value is not restricted to numbers. You can return: * a float (e.g., a linearly decaying mutation strength), * an int (e.g., a discrete number of mutated components), * a bool (e.g., switching on/off a feature after a threshold), * a string (e.g., switching between strategies), or * any other object that the consuming component expects.

This makes schedules suitable for changing discrete algorithm choices as well as continuous numerical parameters.

class Algorithm(objfunc: ObjectiveFunc, search_strategy: SearchStrategy, name: str | None = None, stop_cond: str = 'real_time_limit', progress_metric: str | None = None, max_iterations: int = 1000, max_evaluations: int = 100000.0, real_time_limit: float = 60.0, cpu_time_limit: float = 60.0, objective_target: float = 1e-10, max_patience: int = 100, verbose_timer: float = 0.5, track_median: bool = False, track_worst: bool = False, track_full_objective: bool = False, track_full_population: bool = False, track_diversity: bool = False, checkpoint_file: str | None = None, checkpoint_time_frequency: float | None = None, checkpoint_iteration_frequency: float | None = None, stopping_condition: StoppingCondition | None = None, reporter: str | Reporter | None = None, history_tracker: HistoryTracker | None = None, checkpointer: Checkpointer | None = None, parallel: bool = False, threads: int = 8)[source]

Bases: object

Orchestrates a complete optimisation run.

An Algorithm combines a ObjectiveFunc with a SearchStrategy and manages the iteration loop, stopping conditions, reporting, history tracking, and checkpointing.

All runtime settings can be supplied as plain keyword arguments (e.g., max_iterations=200) or as pre-built objects (StoppingCondition, Reporter, etc.). The keyword-argument style is convenient for quick experiments; the object-based style gives finer control and reusability.

Parameters:
  • objfunc (ObjectiveFunc) – The objective function to optimise.

  • search_strategy (SearchStrategy) – Strategy that defines one iteration of the algorithm.

  • name (str, optional) – Display name for the algorithm (defaults to the strategy’s name).

  • stop_cond (str, optional) – Expression that defines the stopping condition (see StoppingCondition). Default "real_time_limit".

  • progress_metric (str, optional) – Token used to compute the 0-1 progress value for parameter schedules. Defaults to the same tokens as stop_cond.

  • max_iterations (int, optional) – Maximum number of iterations (default 1000).

  • max_evaluations (int, optional) – Maximum number of objective evaluations (default 1e5).

  • real_time_limit (float, optional) – Wall-clock time limit in seconds (default 60).

  • cpu_time_limit (float, optional) – CPU time limit in seconds (default 60).

  • objective_target (float, optional) – Target value for the raw objective (default 1e-10).

  • max_patience (int, optional) – Iterations without improvement before convergence stops (default 100).

  • verbose_timer (float, optional) – Interval in seconds between prints when using the default VerboseReporter (default 0.5).

  • track_diversity (track_median / track_worst / track_full_objective / track_full_population /) – Flags forwarded to the HistoryTracker when one is not supplied explicitly.

  • checkpoint_iteration_frequency (checkpoint_file / checkpoint_time_frequency /) – Arguments used to construct a Checkpointer when checkpointer is not given.

  • stopping_condition (StoppingCondition, optional) – Explicit stopping condition object.

  • reporter (str or Reporter, optional) – Reporter instance or name ("tqdm", "silent", "verbose").

  • history_tracker (HistoryTracker, optional) – Explicit history tracker.

  • checkpointer (Checkpointer, optional) – Explicit checkpointer.

  • parallel (bool, optional) – Whether to evaluate the population in parallel (currently reserved for future use).

  • threads (int, optional) – Number of threads for parallel evaluation (reserved).

property initializer: Initializer
property iterations: int
property evaluations: int
property patience_left: int
property progress: float
property population: Population
gather_parameters() dict[source]

Collect the current parameters of the underlying search strategy.

Returns:

A dictionary of parameter names and their current values.

Return type:

dict

best_solution() Tuple[Any, float][source]

Return the best decoded solution and its raw objective value.

Returns:

best_solution – A pair of the best individual with its objective value.

Return type:

Tuple[Any, float]

best_individual() Tuple[ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool], float][source]

Return the best genotype and its internal fitness value.

Returns:

best_solution – A pair of the best individual with its fitness.

Return type:

Tuple[VectorLike, float]

restart(restart_objfunc: bool = True)[source]

Reset internal counters and, optionally, the objective function.

Parameters:

restart_objfunc (bool, optional) – If True, also reset the objective function’s evaluation counter.

initialize(reset_objfunc: bool = True) Population[source]

Create and evaluate the initial population.

Parameters:

reset_objfunc (bool, optional) – Passed through to restart().

Returns:

The evaluated initial population.

Return type:

Population

step(population: Population | None = None) Population[source]

Execute one iteration of the optimisation loop.

The default implementation performs: parent selection -> perturbation -> evaluation -> survivor selection.

Parameters:

population (Population, optional) – The population at the start of the iteration. If not given, the currently stored population is used.

Returns:

The population after the iteration.

Return type:

Population

resume() Population[source]

Resume an interrupted run from the last checkpoint.

Returns:

The final population after the run completes.

Return type:

Population

optimize(resume: bool = False) Population[source]

Run the optimisation loop until a stopping condition is met.

Parameters:

resume (bool, optional) – If True, do not reset the algorithm state - continue from the current population and counters.

Returns:

The final population.

Return type:

Population

Raises:

KeyboardInterrupt, TerminationException – If the process is interrupted, a checkpoint is attempted before re-raising.

get_state(store_population: bool = False) dict[source]

Serialise the current algorithm state to a dictionary.

Parameters:

store_population (bool, optional) – If True, include the complete genotype matrix.

Returns:

Dictionary representation of the algorithm state.

Return type:

dict

store_state(file_name: str = 'dumped_state.json', readable: bool = False)[source]

Serialise the current algorithm state to a JSON file.

Parameters:
  • file_name (str, optional) – Destination path (default "dumped_state.json").

  • readable (bool, optional) – If True, produce indented JSON (larger but human readable).

to_pandas()[source]

Shorthand for self.history_tracker.to_pandas().

Returns:

Per-iteration summary of tracked metrics.

Return type:

pandas.DataFrame

to_pandas_full_objective()[source]

Shorthand for self.history_tracker.to_pandas_full_objective().

Returns:

Wide-format DataFrame with the full objective vector per generation.

Return type:

pandas.DataFrame

class MemeticAlgorithm(objfunc: ObjectiveFunc, search_strategy: SearchStrategy, local_search: SearchStrategy, improvement_selection: ParentSelection, local_search_frequency: int = 1, local_search_depth: int = 1, keep_improved_solutions: bool = True, name: str | None = None, stop_cond: str = 'real_time_limit', progress_metric: str | None = None, max_iterations: int = 1000, max_evaluations: int = 100000.0, real_time_limit: float = 60.0, cpu_time_limit: float = 60.0, objective_target: float = 1e-10, max_patience: int = 100, track_median: bool = False, track_worst: bool = False, track_complete: bool = False, track_diversity: bool = False, stopping_condition: StoppingCondition | None = None, reporter: str | Reporter | None = None, history_tracker: HistoryTracker | None = None, parallel: bool = False, threads: int = 8)[source]

Bases: Algorithm

A memetic algorithm that interleaves a local search step into the main loop.

After the usual perturbation and evaluation, a subset of the offspring is improved by a separate SearchStrategy (the local search). The improved individuals can either replace the original offspring (Lamarckian, keep_improved_solutions=True) or only transfer their fitness (Baldwinian, keep_improved_solutions=False).

Parameters:
  • objfunc (ObjectiveFunc) – Objective function to optimise.

  • search_strategy (SearchStrategy) – The main search strategy.

  • local_search (SearchStrategy) – Strategy used for local improvement.

  • improvement_selection (ParentSelection) – How to choose which offspring are improved.

  • local_search_frequency (int, optional) – Apply local search every n generations (default 1).

  • local_search_depth (int, optional) – Number of local search iterations per application (default 1).

  • keep_improved_solutions (bool, optional) – If True (Lamarckian), the improved genotypes replace the original offspring. If False (Baldwinian), only the fitness values are transferred.

  • name (str, optional) – Display name; defaults to "Memetic {strategy_name}".

  • stop_cond (optional) – See Algorithm.

  • progress_metric (optional) – See Algorithm.

  • ... (optional) – See Algorithm.

initialize()[source]

Create and evaluate the initial population, then sync the local search.

Returns:

The evaluated initial population.

Return type:

Population

step(population: Population | None = None, time_start: float = 0, verbose: bool = False) Population[source]

Execute one memetic iteration (global step + optional local search).

Parameters:
  • population (Population, optional) – The population at the start of the iteration.

  • time_start (float, optional) – Start time (unused, kept for interface compatibility).

  • verbose (bool, optional) – Whether to produce verbose output (unused).

Returns:

The population after the iteration.

Return type:

Population

get_state(store_population: bool = False) dict[source]

Extend Algorithm.get_state() with local search data.

Parameters:

store_population (bool, optional) – See Algorithm.

Returns:

Dictionary containing the memetic algorithm state.

Return type:

dict

step_info(start_time: int = 0)[source]

Print per-generation information including local search details.

class Checkpointer(checkpoint_file: str, iteration_frequency: int | None = None, time_frequency: float | None = None)[source]

Bases: object

Periodically save and restore the state of an optimisation run.

The checkpointer can be triggered by iteration count, elapsed wall-clock time, or both. It writes the entire Algorithm object to disk using cloudpickle, so that an interrupted run can be resumed later without losing progress.

Parameters:
  • checkpoint_file (str) – Path to the file where the checkpoint will be saved (e.g., "run.pkl").

  • iteration_frequency (int, optional) – Save a checkpoint every n iterations.

  • time_frequency (float, optional) – Save a checkpoint when at least this many seconds have elapsed since the last save.

Notes

At least one of iteration_frequency or time_frequency must be provided; otherwise the checkpointer does nothing and logs a warning.

restart()[source]

Reset the internal timer so that time-based checkpoints are measured from this moment onward.

checkpoint(algorithm: Algorithm)[source]

Evaluate whether a checkpoint should be saved, and perform the save if necessary.

Parameters:

algorithm (Algorithm) – The running algorithm instance.

save(algorithm: Algorithm)[source]

Serialize the algorithm to disk using cloudpickle.

A temporary file is written first and atomically moved to the final location, preventing corruption if the process crashes mid-write. The reporter, parallel flag, and the checkpointer itself are temporarily removed before pickling to avoid serialisation issues, and then restored.

Parameters:

algorithm (Algorithm) – The algorithm to save.

load(file_name: str | None = None, reporter: Reporter | str = 'silent', parallel: bool = False) Algorithm[source]

Restore a previously saved algorithm from a checkpoint file.

Parameters:
  • file_name (str, optional) – Path to the checkpoint file. If not provided, the path given at construction is used.

  • reporter (Reporter or str, optional) – Reporter to attach to the restored algorithm (a Reporter instance or a string like "tqdm", "silent"). Default is "silent".

  • parallel (bool, optional) – Whether parallel evaluation should be enabled after restoration. Default is False.

Returns:

The deserialized algorithm, ready to continue from where it was saved. Ensure you run the algorithm with .resume() so data is not lost.

Return type:

Algorithm

class Reporter[source]

Bases: ABC

Abstract interface for progress reporters.

A reporter is notified at three key moments of an optimisation run: initialisation, after each generation, and at completion. Implementations can display progress bars, log messages, update dashboards, etc.

abstract log_init(algorithm: Algorithm)[source]

Called once, before the main optimisation loop starts.

Parameters:

algorithm (Algorithm) – The algorithm that is about to run.

abstract log_step(algorithm: Algorithm)[source]

Called after each generation.

Parameters:

algorithm (Algorithm) – The running algorithm, with up-to-date population, iteration count, and best solution.

abstract log_end(algorithm: Algorithm)[source]

Called once, after the optimisation loop finishes.

Parameters:

algorithm (Algorithm) – The algorithm that has just finished.

class StoppingCondition(condition_str: str, progress_metric_str: str | None = None, max_iterations: int | None = None, max_evaluations: int | None = None, real_time_limit: float | None = None, cpu_time_limit: float | None = None, objective_target: float | None = None, max_patience: int | None = None, optimization_mode: str = 'max')[source]

Bases: object

Encapsulate the logic that decides when an optimisation run should end.

A stopping condition is built from a logical expression that combines tokens with and, or and parentheses. Each token has a corresponding numeric limit. The same expression (or a separate one) can be used to compute a progress value between 0 and 1 for parameter schedules.

Parameters:
  • condition_str (str) – Logical expression defining when to stop (e.g. "max_iterations or real_time_limit").

  • progress_metric_str (str, optional) – Logical expression defining how to compute the 0-1 progress value. Defaults to condition_str.

  • max_iterations (int, optional) – Maximum number of generations.

  • max_evaluations (int, optional) – Maximum number of objective function evaluations.

  • real_time_limit (float, optional) – Wall-clock time limit in seconds.

  • cpu_time_limit (float, optional) – CPU time limit in seconds.

  • objective_target (float, optional) – Target value for the raw objective.

  • max_patience (int, optional) – Consecutive iterations without improvement before "convergence" triggers.

  • optimization_mode (str, optional) – "max" or "min", how the objective target and convergence are evaluated.

condition_str: str
progress_metric_str: str | None = None
max_iterations: int = None
max_evaluations: int = None
real_time_limit: float = None
cpu_time_limit: float = None
objective_target: float = None
max_patience: int = None
optimization_mode: str = 'max'
restart()[source]

Reset all counters and timers for a fresh run.

step(current_population: Population)[source]

Advance internal counters after one generation.

Parameters:

current_population (Population) – The population at the end of the current generation. Its best objective is used to update convergence tracking.

is_finished(finished: bool = False) bool[source]

Given the state of the algorithm, returns wether we have finished or not.

Parameters:
  • real_time_start (float) – The time in seconds that passed since the algorithm was executed.

  • cpu_time_start (float) – The time in seconds that the CPU has executed code in this algorithm.

Returns:

has_stopped – Whether the algorithm has reached its end

Return type:

bool

get_progress() float[source]

Compute the current progress (0-1) according to the progress metric.

Parameters:
  • gen (int) – The number of generations that has passed.

  • real_time_start (float) – The time in seconds that passed since the algorithm was executed.

  • cpu_time_start (float) – The time in seconds that the CPU has executed code in this algorithm.

Returns:

A value between 0 (start) and 1 (finished).

Return type:

float

get_state()[source]

Return a dictionary with the current state of the stopping condition.

Returns:

Keys include iterations, evaluations, times, and configuration limits.

Return type:

dict

class HistoryTracker(track_best=True, track_median=False, track_worst=False, track_full_objective=False, track_full_population=False, track_parameters=False, track_diversity=False)[source]

Bases: object

Record per-generation metrics and export them as pandas DataFrames.

The tracker is called once per generation (via step()) and stores the requested statistics. After the run the data can be retrieved with to_pandas() (a summary of best, median, worst, diversity, and scheduled parameters) or to_pandas_full_objective() (the full objective vector of every individual at each generation).

Parameters:
  • track_best (bool, optional) – Record the best objective and solution (default True).

  • track_median (bool, optional) – Record the median objective (default False).

  • track_worst (bool, optional) – Record the worst objective (default False).

  • track_full_objective (bool, optional) – Store the complete objective vector of the population at every generation. Enables to_pandas_full_objective().

  • track_full_population (bool, optional) – Store the entire population (genotypes) at every generation. This can consume a lot of memory.

  • track_parameters (bool, optional) – Record the current value of all scheduled parameters (e.g., mutation strength, branch probability).

  • track_diversity (bool, optional) – Compute and store a simple diversity metric (average Euclidean distance from the centroid).

restart()[source]

Clear all recorded data.

Call this when an algorithm is reset to start a fresh run.

step(algorithm: Algorithm)[source]

Record metrics for the current generation.

Parameters:

algorithm (Algorithm) – The running algorithm from which the current population, fitness, objective, and parameters are extracted.

to_pandas()[source]

Return a DataFrame with per-generation summary metrics.

Columns include iteration, best_objective, median_objective, worst_objective, diversity, and one column per scheduled parameter. The DataFrame is intended for easy plotting with seaborn or matplotlib.

Return type:

pandas.DataFrame

to_pandas_full_objective()[source]

Return a wide-format DataFrame of all individual objective values.

Each column Individual_0, Individual_1, … holds the objective of one member of the population across generations. This is useful for boxplots or distribution plots of fitness.

Returns:

Empty DataFrame if track_full_objective was not enabled.

Return type:

pandas.DataFrame

get_state()[source]

Return a dictionary containing the recorded history.

Returns:

Keys include best_objective, best_solutions, etc. Only metrics that were enabled are present.

Return type:

dict

create_reporter(reporter_name: str, **kwargs) Reporter[source]

Instantiate a reporter by name.

Parameters:
  • reporter_name (str) – One of "silent", "tqdm", or "verbose".

  • **kwargs – Forwarded to the reporter constructor.

Returns:

A concrete reporter instance.

Return type:

Reporter

Raises:

ValueError – If reporter_name is not recognised.

class SilentReporter[source]

Bases: Reporter

Reporter that produces no output.

All logging methods are no-ops. Useful for running experiments without visual clutter.

log_init(algorithm: Algorithm)[source]

Called once, before the main optimisation loop starts.

Parameters:

algorithm (Algorithm) – The algorithm that is about to run.

log_step(algorithm: Algorithm)[source]

Called after each generation.

Parameters:

algorithm (Algorithm) – The running algorithm, with up-to-date population, iteration count, and best solution.

log_end(algorithm: Algorithm)[source]

Called once, after the optimisation loop finishes.

Parameters:

algorithm (Algorithm) – The algorithm that has just finished.

class TQDMReporter(resolution: int = 1000, **kwargs)[source]

Bases: Reporter

Reporter that displays a tqdm progress bar.

Parameters:

resolution (int, optional) – Number of ticks in the progress bar (default 1000). Higher values give smoother updates.

log_init(algorithm: Algorithm)[source]

Initialise the progress bar and display the first postfix.

log_step(algorithm: Algorithm)[source]

Update the progress bar with current iteration, evaluations, and fitness.

log_end(algorithm: Algorithm)[source]

Fill the progress bar to 100% and close it.

class VerboseReporter(verbose_timer=0.5, **kwargs)[source]

Bases: Reporter

Reporter that prints a multi-line status block every verbose_timer seconds.

Parameters:

verbose_timer (float, optional) – Minimum interval (in seconds) between printed updates (default 0.5).

log_init(algorithm: Algorithm)[source]

Print a header indicating the start of the optimisation.

log_step(algorithm: Algorithm)[source]

Print a status block if enough time has elapsed.

log_end(algorithm: Algorithm)[source]

Print a final summary of the completed run.

class SearchStrategy(initializer: Initializer, operator: Operator | None = None, parent_sel: ParentSelection | None = None, survivor_sel: SurvivorSelection | None = None, name: str = 'some strategy', random_state: int | Generator | None = None, **kwargs)[source]

Bases: ParametrizableMixin

Orchestrates one iteration of an optimisation loop.

A search strategy holds together an Initializer, an Operator, a ParentSelection, and a SurvivorSelection. Together they define how the population is created, perturbed, and pruned each generation. Subclasses can override any step to implement algorithm-specific logic.

Parameters:
  • initializer (Initializer) – Creates the starting population.

  • operator (Operator, optional) – The perturbation operator (mutation, crossover, …). Defaults to NullOperator.

  • parent_sel (ParentSelection, optional) – Selects which individuals are used to generate offspring. Defaults to NullParentSelection.

  • survivor_sel (SurvivorSelection, optional) – Selects which individuals survive to the next generation. Defaults to NullSurvivorSelection.

  • name (str, optional) – Display name used in reports.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

property population_size: int

Gets the amount of individuals in the population.

gather_parameters()[source]

Collect the current parameters from all sub-components.

Returns:

A flat dictionary with dotted keys like "operator.F", "parent_sel.amount", etc.

Return type:

dict

best_solution() Tuple[Any, float][source]

Returns the best solution found by the search strategy and its fitness.

Returns:

best_solution – A pair of the best individual with its fitness.

Return type:

Tuple[Any, float]

initialize(objfunc: ObjectiveFunc) Population[source]

Initializes the optimization search strategy.

Parameters:

objfunc (ObjectiveFunc) – Objective function to be optimized.

Returns:

population – The initial population to be used in the algoritm.

Return type:

Population

evaluate_population(population: Population, parallel: bool = False, threads: int = 8) Population[source]

Calculates the fitness of the individuals on the population.

Parameters:
  • population (Population)

  • parallel (bool, optional) – Whether to evaluate the individuals in the population in parallel.

  • threads (int, optional) – Number of processes to use at once if calculating the fitness in parallel.

Returns:

population – The population with the fitness values recorded.

Return type:

Population

select_parents(population: Population, amount: int | None = None) Population[source]

Selects the individuals that will be perturbed in this generation to generate the offspring.

Parameters:

population (Population) – The current population of the search strategy.

Returns:

parents – A pair of the list of individuals considered as parents and their position in the original population.

Return type:

Population

perturb(parents: Population, **kwargs) Population[source]

Applies operators to the population to get the next generation of individuals.

Parameters:

parents (Population) – The current parents that will be used in the search strategy.

Returns:

offspring – The list of individuals modified by the operators of the search strategy.

Return type:

Population

repair_population(population: Population) Population[source]

Repairs the individuals in the population to make them fulfill the problem’s restrictions.

Parameters:

population (Population) – The population to be repaired

Returns:

repaired_population – The population of repaired individuals

Return type:

Population

select_individuals(population: Population, offspring: Population, **kwargs) Population[source]

Selects the individuals that will pass to the next generation.

Parameters:
  • population (Population) – The current population of the search strategy.

  • offspring (Population) – The list of individuals modified by the operators of the search strategy.

Returns:

offspring – The list of individuals selected for the next generation.

Return type:

Population

step(progress: float)[source]

Update internal parameters and forward progress to sub-components.

Parameters:

progress (float) – Current progress of the algorithm (0-1).

get_state(store_population: bool = False) dict[source]

Gets the current state of the search strategy as a dictionary.

Parameters:

show_population (bool, optional) – Save the state of the current population.

Returns:

state – The complete state of the search strategy.

Return type:

dict

extra_step_info()[source]

Hook called after each generation (intended for subclasses).

extra_report()[source]

Hook called at the end of the optimisation (intended for subclasses).

class SearchStrategyFromLambda(initializer: Callable | Initializer, operator: Callable | Operator | None = None, parent_sel: Callable | ParentSelection | None = None, survivor_sel: Callable | SurvivorSelection | None = None, name: str = 'Strategy from lambda', encoding: Encoding | None = None, encode_fn: Callable | None = None, decode_fn: Callable | None = None, parent_selection_amount: int | None = None, pop_size: int = 100, random_state: int | Generator | None = None, **kwargs)[source]

Bases: SearchStrategy

Strategy whose components can be plain functions.

Accepts each component as either a properly constructed object or a callable; if a callable is provided it is automatically wrapped with the appropriate *FromLambda class. This is the simplest way to build a custom strategy in one go.

Parameters:
  • initializer (callable or Initializer) – Function (random_state) -> genotype, or an initializer instance.

  • operator (callable or Operator, optional) – Function (population, initializer, random_state, **kwargs) -> Population, or an operator instance.

  • parent_sel (callable or ParentSelection, optional) – Function (population, amount, random_state, **kwargs) -> indices, or a selection instance.

  • survivor_sel (callable or SurvivorSelection, optional) – Function (parent_fitness, offspring_fitness, random_state, **kwargs) -> indices, or a selection instance.

  • name (str, optional) – Display name (default "Strategy from lambda").

  • encoding (Encoding, optional) – Encoding that wraps encode/decode; overridden by encode_fn/decode_fn if both are given.

  • decode_fn (encode_fn /) – Standalone encode/decode functions.

  • parent_selection_amount (int, optional) – Amount of parents to select (used only when wrapping a callable parent_sel).

  • pop_size (int, optional) – Population size (used only when wrapping a callable initializer). Default 100.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Forwarded to SearchStrategy.

class Population(objfunc: ObjectiveFunc, genotype_matrix: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool], encoding: Encoding | None = None)[source]

Bases: object

Container for a set of candidate solutions and their fitness.

A Population holds the genotype matrix, fitness and objective values, historical bests, and the current best individual. It is the central data structure passed between components of the optimisation loop.

Parameters:
  • objfunc (ObjectiveFunc) – The objective function that will evaluate the population.

  • genotype_matrix (ndarray) – 2-D array of shape (N, M) containing the genotypes.

  • encoding (Encoding, optional) – The encoding used to translate between genotype and phenotype. Defaults to DefaultEncoding.

best_individual() Tuple[ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool], float][source]

Return the best genotype and its maximised fitness value.

Returns:

  • best_genotype (MatrixLike) – The genotype vector of the best individual.

  • best_fitness (float) – The internal fitness (always maximised).

best_solution() Tuple[Any, float][source]

Return the best decoded solution and its raw objective value.

Returns:

  • solution (Any) – The decoded phenotype of the best individual.

  • objective (float) – The raw objective value.

update_genotype(genotype_source: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool] | Population) Population[source]

Replace the genotype matrix.

Parameters:

genotype_source (ndarray or Population) – New genotypes. If a Population is given, its genotype matrix is used.

Returns:

self, with updated genotypes and, if the size changed, re-initialised fitness and historical bests.

Return type:

Population

take_selection(selection_idx: ndarray[tuple[int, ...], integer] | ndarray[tuple[int, ...], uint8 | bool]) Population[source]

Takes a subset of the population given a mask.

Parameters:

selection_idx (ndarray) – An array of indices or a mask that indicate which individuals to take from the population.

Returns:

selected_population – A copy of the population containing only the chosen individuals.

Return type:

Population

apply_selection(selected_pop: Population, selection_idx: ndarray[tuple[int, ...], integer] | ndarray[tuple[int, ...], uint8 | bool]) Population[source]

Replaces the chosen individuals from the input population to the current population.

Parameters:
  • selected_pop (Population) – Population where to take the individuals that will replace the ones in the population.

  • selection_idx (ndarray) – An array of indices or a mask that indicate which individuals to take from the population.

Returns:

self

Return type:

Population

take_slice(mask: ndarray[tuple[int, ...], integer] | ndarray[tuple[int, ...], uint8 | bool]) Population[source]

Takes a subset of the components in the population vectors.

Parameters:

mask (ndarray) – An array of indices or a mask that indicate which components to take from each vector in the population.

Returns:

sliced_population – A copy of the population containing the masked individuals.

Return type:

Population

apply_slice(sliced_pop: Population, mask: ndarray[tuple[int, ...], integer] | ndarray[tuple[int, ...], uint8 | bool]) Population[source]

Apply the values of the population to a subset of the components of the population vectors.

Parameters:
  • sliced_pop (Population) – Population where to take the individuals from which we will take the components that will replace the ones in the current population.

  • mask (ndarray) – An array of indices or a mask that indicate which components to take from each vector in the population.

Returns:

self

Return type:

Population

static join_populations(population1: Population, population2: Population) Population[source]

Concatenate two populations into a new one.

Parameters:
Returns:

A new population containing all individuals from both inputs.

Return type:

Population

join(other_population: Population) Population[source]

Adds to the current population the individuals of the input population.

Parameters:

other_population (Population) – Population that will be concatenated with the current one.

Returns:

joined_populations – A population containing both the individuals from the current population and the ones from the input population.

Return type:

Population

sort_population() Population[source]

Sorts the individuals by fitness.

Returns:

self

Return type:

Population

update_best_from_parents(parents: Population) Population[source]

Update the best solution if a better one exists in parents.

Parameters:

parents (Population) – Population whose best individual may improve the current one.

Returns:

self, with possibly updated best, best_fitness, and best_objective.

Return type:

Population

step(_progress: float = 0) Population[source]

Updates the best solution in the population.

Returns:

self

Return type:

Population

repeat(amount: int = 2) Population[source]

Duplicates the individuals of the population.

Parameters:

amount (int, optional) – The amount of times to repeat the individuals in the population.

Returns:

repeated_population

Return type:

Population

calculate_fitness(parallel: bool = False, threads: int = 8) ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Calculates the fitness of the individual if it has not been calculated before

Parameters:
  • parallel (bool, optional) – Whether to evaluate the individuals in the population in parallel.

  • threads (int, optional) – Number of processes to use at once if calculating the fitness in parallel.

Returns:

fitness

Return type:

ndarray

repair_solutions() Population[source]

Repairs the solutions in the population.

Returns:

self

Return type:

Population

decode(encoding: Encoding | None = None) Iterable[source]

Return the population passed through the decoding function defined in the encoding.

Returns:

decoded_population

Return type:

Any

decode_params(encoding: Encoding | None = None) Iterable[source]

Decode the auxiliary parameters stored in the genotype.

Only works with ParameterExtendingEncoding.

Parameters:

encoding (Encoding, optional) – Encoding to use; defaults to self.encoding.

Returns:

Dictionary of parameter arrays, or None if the encoding does not support extended parameters.

Return type:

dict or None

encode(encoding: Encoding | None = None) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Encode the current population using the given encoding.

Parameters:

encoding (Encoding, optional) – Encoding to use; defaults to self.encoding.

Returns:

The encoded genotype matrix.

Return type:

MatrixLike

get_state() dict[source]

Return a dictionary with the current population state.

Returns:

Keys include genotype_matrix, fitness, objective, historical bests, and the best individual.

Return type:

dict

debug_repr(max_solutions: int = 5, max_vars: int = 5) str[source]

Return a compact string representation for debugging.

Parameters:
  • max_solutions (int, optional) – Maximum number of rows to include in the preview.

  • max_vars (int, optional) – Maximum number of columns to include in the preview.

Return type:

str

class Encoding(decode_as_array: bool = False, name=None, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Translate between internal genotypes and problem-specific phenotypes.

An Encoding is responsible for converting a population matrix (the internal representation used by operators) into a collection of solutions that the objective function understands, and vice versa.

Parameters:
  • decode_as_array (bool, optional) – If True, decode() returns a NumPy array instead of an iterable of arbitrary objects. Default False.

  • name (str, optional) – Display name for this encoding.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

gather_params() dict[source]

Overridable thin wrapper around get_params

abstract encode(solutions: Iterable) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Encodes a list of solutions to our problem to an population matrix.

Parameters:

solutions (Iterable) – Solutions that should be encoded.

Returns:

population – Population array.

Return type:

ndarray

abstract decode(population: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) Iterable[source]

Decodes a population matrix into a list/array of solutions.

Parameters:

population (ndarray) – Population that should be decoded.

Returns:

solutions – List/array of solutions.

Return type:

Iterable

get_state() dict[source]
class EncodingFromLambda(encode_fn: Callable, decode_fn: Callable, **kwargs)[source]

Bases: Encoding

Encoding built from two callables.

Parameters:
  • encode_fn (callable) – (solutions) -> population_matrix.

  • decode_fn (callable) – (population_matrix) -> solutions.

  • decode_as_array (bool, optional) – See Encoding.

  • **kwargs – Forwarded to Encoding.

encode(solution: Iterable) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Encodes a list of solutions to our problem to an population matrix.

Parameters:

solutions (Iterable) – Solutions that should be encoded.

Returns:

population – Population array.

Return type:

ndarray

decode(population: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) Iterable[source]

Decodes a population matrix into a list/array of solutions.

Parameters:

population (ndarray) – Population that should be decoded.

Returns:

solutions – List/array of solutions.

Return type:

Iterable

class DefaultEncoding(decode_as_array: bool = True)[source]

Bases: Encoding

Identity encoding - the internal genotype is used directly.

No transformation is applied; encode() and decode() return their arguments unchanged. This is the encoding used when no other is specified.

Parameters:

decode_as_array (bool, optional) – See Encoding. Default True.

encode(solution: Iterable) ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool][source]

Encodes a list of solutions to our problem to an population matrix.

Parameters:

solutions (Iterable) – Solutions that should be encoded.

Returns:

population – Population array.

Return type:

ndarray

decode(population: ndarray[tuple[int, int], floating] | ndarray[tuple[int, int], integer] | ndarray[tuple[int, int], uint8 | bool]) Iterable[source]

Decodes a population matrix into a list/array of solutions.

Parameters:

population (ndarray) – Population that should be decoded.

Returns:

solutions – List/array of solutions.

Return type:

Iterable

class Initializer(dimension: int, population_size: int = 1, encoding: Encoding | None = None, random_state: int | Generator | None = None)[source]

Bases: ABC

Abstract base for all population initializers.

An initializer creates the first generation of individuals. It must provide a way to generate a single random genotype vector (a 1-D NumPy array) via generate_random() and can optionally wrap it with a different definition of an individual via generate_individual().

Parameters:
  • dimension (int) – Length of the genotype vector.

  • population_size (int, optional) – Number of individuals to generate (default 1).

  • encoding (Encoding, optional) – Encoding that will be attached to every individual. Defaults to DefaultEncoding.

  • random_state (RNGLike, optional) – Random number generator.

abstract generate_random() ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Generate a single random genotype vector (1-D array).

Returns:

A newly generated genotype vector (1-D array).

Return type:

VectorLike

generate_individual() ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Generate a single individual.

By default simply delegates to generate_random(). Returns a newly generated individual (a 1-D array).

Override this method if your initializer needs to distinguish between a randomly initialize individual and a solution generated with another strategy (See SeedProbInitializer).

Returns:

A newly generated individual.

Return type:

Any

generate_population(objfunc: ObjectiveFunc, n_individuals: int | None = None) Population[source]

Create a fully formed population of n_individuals individuals.

Parameters:
  • objfunc (ObjectiveFunc) – Objective function that will be propagated to each individual.

  • n_individual (int, optional) – Number of individuals to generate

Returns:

generated_population – Newly generated population.

Return type:

Population

get_state() dict[source]

Return a minimal dictionary identifying this initializer.

Returns:

Dictionary with key "class_name".

Return type:

dict

class InitializerFromLambda(generator: Callable, dimension: int, pop_size: int = 1, encoding: Encoding | None = None, random_state: int | Generator | None = None)[source]

Bases: Initializer

Initializer that uses a user-provided function to generate individuals.

Parameters:
  • generator (callable) – A function (random_state) -> genotype that returns a single genotype vector.

  • dimension (int) – Length of the genotype vector.

  • pop_size (int, optional) – Number of individuals to generate (default 1).

  • encoding (Encoding, optional) – Encoding attached to every individual.

  • random_state (RNGLike, optional) – Random number generator.

generate_random() ndarray[tuple[int], floating] | ndarray[tuple[int], integer] | ndarray[tuple[int], uint8 | bool][source]

Generate a single random genotype vector (1-D array).

Returns:

A newly generated genotype vector (1-D array).

Return type:

VectorLike

class ParentSelection(name: str | None = None, amount: int | None = None, random_state: int | Generator | None = None, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Abstract base for all parent selection methods.

A parent selection chooses which individuals from the current population will be used to generate offspring. Subclasses must implement select(), which returns a new Population containing only the selected individuals.

Parameters:
  • name (str, optional) – Display name for this selection method.

  • amount (int, optional) – Default number of individuals to select. Can be overridden at call time.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

gather_params() dict[source]

Return the current parameter dictionary (thin wrapper around get_params()).

abstract select(population: Population, amount: int | None = None) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – List of selected individuals.

Return type:

Population

get_state() dict[source]

Return a dictionary with the selection method’s configuration.

Returns:

Keys include class_name, name, and all current parameters.

Return type:

dict

class NullParentSelection(name: str | None = 'Nothing', **kwargs)[source]

Bases: ParentSelection

Null parent selection, returns the whole population unchanged.

This is the identity element: no individuals are filtered out. Useful when the algorithm does not require a parent selection step (e.g., random search or certain evolution strategies).

Parameters:
  • name (str, optional) – Display name. Default "Nothing".

  • **kwargs – Keyword arguments forwarded to ParentSelection.

select(population: Population, amount: int | None = None) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – List of selected individuals.

Return type:

Population

class ParentSelectionFromLambda(selection_fn: Callable, name: str | None = None, amount: int | None = None, random_state: int | Generator | None = None, **kwargs)[source]

Bases: ParentSelection

Parent selection that wraps a user-supplied function.

The function receives the population, the number of individuals to select, a random state, and any stored keyword arguments, and must return an array of selected indices.

Parameters:
  • selection_fn (callable) – A function (population, amount, random_state, **kwargs) -> indices.

  • name (str, optional) – Display name (defaults to the function’s __name__).

  • amount (int, optional) – Default number of individuals to select.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Keyword arguments forwarded to ParentSelection.

select(population: Population, amount: int | None = None) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – List of selected individuals.

Return type:

Population

create_parent_selection(method: str, name: str | None = None, amount: int | None = None, random_state: int | Generator | None = None, **kwargs) ParentSelection[source]

Create a parent selection method by name.

Parameters:
  • method (str) – Key into parent_sel_map, or a null alias.

  • name (str, optional) – Display name for the selection method.

  • amount (int, optional) – Default number of parents to select.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Additional parameters forwarded to the selection function.

Returns:

The wrapped selection method.

Return type:

ParentSelectionFromLambda or NullParentSelection

add_parent_selection_entry(selection_fn: callable, selection_method_name: str)[source]

Register a new parent selection method.

Parameters:
  • selection_fn (callable) – A function with the parent selection signature.

  • selection_method_name (str) – Name under which to register the method. If it already exists, a warning is logged.

class ParentSelectionDef(selection_fn: callable, params: dict = <factory>, forced_params: dict = <factory>)[source]

Bases: object

Wrapper that turns a raw parent-selection function into a callable.

Parameters:
  • selection_fn (callable) – Function (fitness, amount, random_state, **kwargs) -> indices.

  • params (dict, optional) – Default keyword arguments merged with user-supplied ones.

  • forced_params (dict, optional) – Keyword arguments that always override user-supplied ones.

selection_fn: callable
params: dict
forced_params: dict
class Operator(name: str | None = None, encoding: Encoding | None = None, preserves_order: bool = False, random_state: int | Generator | None = None, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Abstract base for all perturbation operators.

An Operator modifies a population (typically by applying mutation, crossover, or a composite of several steps). Subclasses must implement evolve().

Parameters:
  • name (str, optional) – Display name for this operator.

  • encoding (Encoding, optional) – Post-processing applied to the genotype matrix after the operator runs. Defaults to DefaultEncoding.

  • preserves_order (bool, optional) – If True, the operator keeps individuals in the same order (useful for one-to-one survivor selection). Default False.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

gather_params()[source]

Return the current parameter dictionary (thin wrapper around get_params()).

abstract evolve(population: Population, initializer: Initializer | None = None) Population[source]

Evolves an population using a given strategy.

Parameters:
  • population (Population) – The population that will be used.

  • initializer (Initialize, optional) – The population initializer of the algorithm (used for randomly generating individuals).

Returns:

new_population – The modified population.

Return type:

Population

step(progress: float = 0)[source]

Updates the internal parameters.

get_state() dict[source]

Gets the current state of the algorithm as a dictionary.

Returns:

state – The complete state of the operator.

Return type:

dict

class OperatorFromLambda(operator_fn: Callable, name: str | None = None, encoding: Encoding | None = None, preserves_order: bool = False, random_state: int | Generator | None = None, **kwargs)[source]

Bases: Operator

Operator that wraps a user‑supplied function.

The function receives a Population, an Initializer, a random state, and any stored keyword arguments, and must return a modified Population.

Parameters:
  • operator_fn (callable) – A function (population, initializer, random_state, **kwargs) -> Population.

  • name (str, optional) – Display name (defaults to the function’s __name__).

  • encoding (Encoding, optional) – See Operator.

  • preserves_order (bool, optional) – See Operator.

  • random_state (RNGLike, optional) – See Operator.

  • **kwargs – Keyword arguments forwarded to Operator and also passed to operator_fn on each call.

evolve(population: Population, initializer: Initializer | None = None) Population[source]

Evolves an population using a given strategy.

Parameters:
  • population (Population) – The population that will be used.

  • initializer (Initialize, optional) – The population initializer of the algorithm (used for randomly generating individuals).

Returns:

new_population – The modified population.

Return type:

Population

class NullOperator(name: str | None = None)[source]

Bases: Operator

Operator class that returns the individual without changes. Surprisingly useful.

Since it’s a no-op, it has the preserves_order flag set to True.

Parameters:

name (str, optional) – Name that is associated with the operator.

evolve(population: Population, *args) Population[source]

Evolves an population using a given strategy.

Parameters:
  • population (Population) – The population that will be used.

  • initializer (Initialize, optional) – The population initializer of the algorithm (used for randomly generating individuals).

Returns:

new_population – The modified population.

Return type:

Population

create_operator(method: str, encoding: Encoding | None = None, random_state: int | Generator | None = None, name: str | None = None, **kwargs) OperatorFromLambda[source]

Create an operator by name from any registry.

The method string can be a simple key (e.g., "gauss") or dot-separated "registry.key" (e.g., "crossover.one_point").

Parameters:
  • method (str) – Operator key, possibly with registry prefix.

  • encoding (Encoding, optional) – Encoding applied to the genotype after the operator runs.

  • random_state (RNGLike, optional) – Random number generator.

  • name (str, optional) – Display name; defaults to method.

  • **kwargs – Parameters forwarded to the underlying operator function.

Returns:

The wrapped operator.

Return type:

OperatorFromLambda

Raises:

ValueError – If the operator cannot be found.

add_operator_entry(operator_fn: callable, operator_name: str, operator_registry: str = 'custom', preserves_order=False)[source]

Register a new operator so it can be created by create_operator().

Parameters:
  • operator_fn (callable) – A callable that follows the operator signature expected by OperatorFromLambda. Usually wrapped with OperatorFnDef, OperatorRandomDef, etc.

  • operator_name (str) – Key under which the operator is registered.

  • operator_registry (str, optional) – Registry name (default "custom"). If the registry does not exist, it is created.

  • preserves_order (bool, optional) – If True, the operator is marked as order-preserving, meaning individuals retain their position when applying it. Default False.

class OperatorFnDef(operator_fn: callable, params: dict = <factory>, forced_params: dict = <factory>)[source]

Bases: object

Bridge a matrix-to-matrix operator function into an Operator.

This wrapper accepts a callable that operates on a genotype matrix, fitness array, and random state, and turns it into an object that can be used directly on a Population. It merges user-supplied keyword arguments with stored defaults and forced parameters, then invokes the underlying function and updates the population’s genotype.

Parameters:
  • operator_fn (callable) – Function with signature (population_matrix, fitness_array, random_state, **kwargs) -> np.ndarray.

  • params (dict, optional) – Default keyword arguments for the operator.

  • forced_params (dict, optional) – Keyword arguments that always override user-supplied ones.

operator_fn: callable
params: dict
forced_params: dict
class SurvivorSelection(name: str | None = None, preserves_order: bool = False, random_state: int | Generator | None = None, **kwargs)[source]

Bases: ParametrizableMixin, ABC

Abstract base for all survivor selection methods.

A survivor selection decides which individuals from the current population and the newly generated offspring will form the next generation. Subclasses must implement select().

Parameters:
  • name (str, optional) – Display name for this selection method.

  • preserves_order (bool, optional) – If True, the order of individuals is kept (useful for one-to-one competition schemes). Default False.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Additional keyword arguments stored as schedulable parameters.

gather_params()[source]

Return the current parameter dictionary (thin wrapper around get_params()).

abstract select(population: Population, offspring: Population) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – Population containing only the selected survivors.

Return type:

Population

get_state() dict[source]

Return a dictionary with the selection method’s configuration.

Returns:

Keys include class_name, name, and all current parameters.

Return type:

dict

class NullSurvivorSelection(name: str | None = 'Nothing', **kwargs)[source]

Bases: SurvivorSelection

Null survivor selection, offspring replace parents entirely.

This is the identity element for generational replacement: all parents are discarded and all offspring survive. The population size must be maintained by the offspring.

Parameters:
  • name (str, optional) – Display name. Default "Nothing".

  • **kwargs – Keyword arguments forwarded to SurvivorSelection.

select(population: Population, offspring: Population) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – Population containing only the selected survivors.

Return type:

Population

class SurvivorSelectionFromLambda(selection_fn: Callable, name: str | None = None, preserves_order: bool = False, random_state: int | Generator | None = None, **kwargs)[source]

Bases: SurvivorSelection

Survivor selection that wraps a user-supplied function.

The function receives the parent population, the offspring population, a random state, and any stored keyword arguments, and must return an array of indices into the concatenated pool.

Parameters:
  • selection_fn (callable) – A function (parents, offspring, random_state, **kwargs) -> indices.

  • name (str, optional) – Display name (defaults to the function’s __name__).

  • preserves_order (bool, optional) – See SurvivorSelection.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Keyword arguments forwarded to SurvivorSelection.

select(population: Population, offspring: Population) Population[source]

Takes a population with its offspring and returns the individuals that survive to produce the next generation.

Parameters:
  • population (Population) – Population of individuals that will be selected.

  • offspring (Population) – Newly generated individuals to be selected.

Returns:

selected – Population containing only the selected survivors.

Return type:

Population

create_survivor_selection(method: str, name: str | None = None, random_state: int | Generator | None = None, **kwargs)[source]

Create a survivor selection method by name.

Parameters:
  • method (str) – Key into surv_method_map, or a null alias.

  • name (str, optional) – Display name for the selection method.

  • random_state (RNGLike, optional) – Random number generator.

  • **kwargs – Additional parameters forwarded to the selection function.

Returns:

The wrapped selection method.

Return type:

SurvivorSelectionFromLambda or NullSurvivorSelection

add_survivor_selection_entry(selection_fn: callable, selection_method_name: str, preserves_order: bool = False)[source]

Register a new survivor selection method.

Parameters:
  • selection_fn (callable) – A function with the survivor selection signature.

  • selection_method_name (str) – Name under which to register the method. If it already exists, a warning is logged.

  • preserves_order (bool, optional) – Whether the method preserves the order of individuals.

class SurvivorSelectionDef(selection_fn: callable, params: dict = <factory>, forced_params: dict = <factory>, preserves_order: bool = False)[source]

Bases: object

Wrapper that turns a raw survivor-selection function into a callable.

Parameters:
  • selection_fn (callable) – Function (parent_fitness, offspring_fitness, random_state, **kwargs) -> indices.

  • params (dict, optional) – Default keyword arguments merged with user-supplied ones.

  • forced_params (dict, optional) – Keyword arguments that always override user-supplied ones.

  • preserves_order (bool, optional) – If True, the selection method keeps individuals in the same order. Default False.

selection_fn: callable
params: dict
forced_params: dict
preserves_order: bool = False