Variable Neighbourhood Search
A (μ+λ) evolutionary algorithm with a self-adapting per-individual mutation rate.
Self-adapting mutation rate
Each individual carries its own mutation rate in its genome. When the algorithm produces an offspring from a parent, the rate is perturbed by a lognormal step:
where \(\tau\) is mutation_rate_tau.
The result is clamped to [minimum_mutation_rate, maximum_mutation_rate].
Larger \(\tau\) widens the per-generation step in log-space, letting the population
explore more aggressively; smaller \(\tau\) keeps each offspring close to its
parent’s rate.
Population structure
The population is (μ+λ):
population_sizeis λ — the total number of offspring per generation.offspring_sizeis the offspring count per parent, so the number of parents is μ = population_size / offspring_size.selectionchooses the μ parents each generation (same operator types asGeneticAlgorithm).
Example
from daitum_configuration import (
Selection,
SelectionType,
VariableNeighbourhoodSearch,
)
algorithm = VariableNeighbourhoodSearch(
population_size=128,
offspring_size=16, # μ = 128 / 16 = 8 parents
initial_mutation_rate=0.2,
mutation_rate_tau=0.5,
selection=Selection.selection(SelectionType.TOURNAMENT_SELECTION, pool_size=4),
)
API reference
VariableNeighbourhoodSearch configuration.
- class VariableNeighbourhoodSearch(log_info=False, evaluations=100000, max_evaluations_without_improvement=10000, max_time_without_improvement=300, min_improvement=1e-06, max_restart_count=0, prng_seed=None, time_limit=60, initial_mutation_rate=(1 / NUM_VARIABLES), minimum_mutation_rate=(1 / NUM_VARIABLES), maximum_mutation_rate=1.0, mutation_rate_tau=0.5, offspring_size=64, population_size=NUM_VARIABLES, mutation=<factory>, selection=<factory>)[source]
Variable Neighbourhood Search — a (μ+λ) evolutionary algorithm with a self-adapting mutation rate.
Each individual carries its own mutation rate as part of its genome. When producing offspring, the rate is perturbed by a lognormal step:
\[\text{childRate} = \text{parentRate} \times \exp(\tau \cdot \mathcal{N}(0, 1))\]where \(\tau\) is
mutation_rate_tau. The result is clamped to[minimum_mutation_rate, maximum_mutation_rate], and the offspring inherits the new rate alongside the mutated genome. Larger \(\tau\) widens the per-generation step in log-space.The population is (μ+λ):
population_sizeis λ (total offspring per generation) and the number of parents μ ispopulation_size / offspring_size.selectionpicks the μ parents each generation.- initial_mutation_rate: float | NumericExpression | Parameter | Calculation = (1 / NUM_VARIABLES)
Mutation rate used to seed each individual at the start of the run (0–1).
- minimum_mutation_rate: float | NumericExpression | Parameter | Calculation = (1 / NUM_VARIABLES)
Lower clamp on per-individual mutation rate (0–1).
- maximum_mutation_rate: float | NumericExpression | Parameter | Calculation = 1.0
Upper clamp on per-individual mutation rate (0–1).
- mutation_rate_tau: float | NumericExpression | Parameter | Calculation = 0.5
Log-normal learning rate τ controlling the magnitude of per-offspring mutation-rate steps:
childRate = parentRate × exp(τ × N(0, 1)). Must be non-negative; larger values widen the step distribution.
- offspring_size: int | NumericExpression | Parameter | Calculation = 64
Offspring produced per parent each generation. Combined with
population_sizethis fixes μ =population_size / offspring_size.
- population_size: int | NumericExpression | Parameter | Calculation = NUM_VARIABLES
Total offspring per generation — λ in (μ+λ) notation.