API Reference
Complete API documentation for PyRADE.
Core Classes
Main Differential Evolution algorithm implementation.
This module provides the core DifferentialEvolution class with fully vectorized operations for high performance.
- class pyrade.core.algorithm.DifferentialEvolution(objective_func: Callable[[ndarray], float], bounds: Tuple[float, float] | ndarray, mutation: Any | None = None, crossover: Any | None = None, selection: Any | None = None, pop_size: int = 50, max_iter: int = 1000, seed: int | None = None, verbose: bool = False, show_progress: bool = False, callback: Callable | None = None)[source]
Bases:
objectMain Differential Evolution optimizer with vectorized operations.
This implementation uses aggressive vectorization to process entire populations at once, achieving significant performance improvements over monolithic implementations.
Features: - Fully vectorized (processes entire population at once) - Strategy pattern for operators (easy to extend) - Professional API (fit/predict style) - Progress tracking and callbacks - Progress bar support (tqdm integration) - Comprehensive logging support
- Parameters:
objective_func (callable) – Function to minimize: f(x) -> float
bounds (tuple or array) – (lower_bound, upper_bound) or [(lb1, ub1), (lb2, ub2), …]
mutation (MutationStrategy, optional) – Mutation strategy (default: DE/rand/1 with F=0.8)
crossover (CrossoverStrategy, optional) – Crossover strategy (default: Binomial with CR=0.9)
selection (SelectionStrategy, optional) – Selection strategy (default: Greedy)
pop_size (int, default=50) – Population size (must be >= 4)
max_iter (int, default=1000) – Maximum iterations (must be >= 1)
seed (int, optional) – Random seed for reproducibility
verbose (bool, default=False) – Print progress information
show_progress (bool, default=False) – Show progress bar (requires tqdm)
callback (callable, optional) – Called after each iteration: callback(iteration, best_fitness, best_solution)
- best_solution_
Best solution found
- Type:
ndarray
- optimize() : dict
Run optimization and return results
Examples
>>> def sphere(x): ... return sum(x**2) >>> >>> optimizer = DifferentialEvolution( ... objective_func=sphere, ... bounds=(-100, 100), ... pop_size=50, ... max_iter=1000 ... ) >>> result = optimizer.optimize() >>> print(f"Best fitness: {result['best_fitness']}")
- __init__(objective_func: Callable[[ndarray], float], bounds: Tuple[float, float] | ndarray, mutation: Any | None = None, crossover: Any | None = None, selection: Any | None = None, pop_size: int = 50, max_iter: int = 1000, seed: int | None = None, verbose: bool = False, show_progress: bool = False, callback: Callable | None = None)[source]
Initialize Differential Evolution optimizer.
- optimize() Dict[str, Any][source]
Run the optimization.
- Returns:
‘best_solution’: Best solution found ‘best_fitness’: Best fitness value ‘n_iterations’: Number of iterations run ‘history’: Optimization history ‘success’: Whether optimization succeeded ‘time’: Total optimization time
- Return type:
dict with keys
Population management for Differential Evolution.
This module provides efficient vectorized population operations.
- class pyrade.core.population.Population(pop_size: int, dim: int, bounds: Tuple[float, float] | ndarray, seed: int | None = None)[source]
Bases:
objectManages the population of candidate solutions.
This class handles population initialization, storage, and provides vectorized operations for efficient population management.
- Parameters:
- vectors
Population vectors
- Type:
ndarray, shape (pop_size, dim)
- fitness
Fitness values for each individual
- Type:
ndarray, shape (pop_size,)
- best_vector
Best solution vector
- Type:
ndarray, shape (dim,)
- __init__(pop_size: int, dim: int, bounds: Tuple[float, float] | ndarray, seed: int | None = None)[source]
Initialize population.
- initialize_random()[source]
Initialize population with random vectors within bounds.
Uses Latin Hypercube Sampling for better space coverage.
- evaluate(objective_func: Callable[[ndarray], float]) ndarray[source]
Evaluate fitness for all individuals in population.
- Parameters:
objective_func (callable) – Objective function to minimize
- Returns:
fitness – Fitness values
- Return type:
ndarray, shape (pop_size,)
- evaluate_vectors(vectors: ndarray, objective_func: Callable[[ndarray], float]) ndarray[source]
Evaluate fitness for given vectors.
- Parameters:
vectors (ndarray, shape (pop_size, dim)) – Vectors to evaluate
objective_func (callable) – Objective function to minimize
- Returns:
fitness – Fitness values
- Return type:
ndarray, shape (pop_size,)
Operators
Mutation Strategies
Mutation strategies for Differential Evolution.
This module provides various mutation strategies with fully vectorized implementations for high performance.
- class pyrade.operators.mutation.MutationStrategy[source]
Bases:
ABCAbstract base class for mutation strategies.
All mutation strategies should inherit from this class and implement the apply() method.
- abstractmethod apply(population, fitness, best_idx, target_indices)[source]
Apply mutation to generate mutant vectors.
- Parameters:
population (ndarray, shape (pop_size, dim)) – Current population
fitness (ndarray, shape (pop_size,)) – Fitness values
best_idx (int) – Index of best individual
target_indices (ndarray, shape (pop_size,)) – Indices being mutated
- Returns:
mutants – Mutant vectors
- Return type:
ndarray, shape (pop_size, dim)
- class pyrade.operators.mutation.DErand1(F=0.8)[source]
Bases:
MutationStrategyDE/rand/1: v = x_r1 + F * (x_r2 - x_r3)
Most common DE mutation strategy. Selects three random distinct individuals and creates mutant from their differences.
- Parameters:
F (float, default=0.8) – Mutation factor (differential weight)
Notes
This is the most widely used mutation strategy, providing a good balance between exploration and exploitation.
- class pyrade.operators.mutation.DEbest1(F=0.8)[source]
Bases:
MutationStrategyDE/best/1: v = x_best + F * (x_r1 - x_r2)
Exploitative strategy using best individual as base vector. Converges faster but may get stuck in local optima.
- Parameters:
F (float, default=0.8) – Mutation factor (differential weight)
Notes
More exploitative than DE/rand/1. Good for unimodal functions but may converge prematurely on multimodal problems.
- class pyrade.operators.mutation.DEcurrentToBest1(F=0.8)[source]
Bases:
MutationStrategyDE/current-to-best/1: v = x_i + F * (x_best - x_i) + F * (x_r1 - x_r2)
Balances exploration and exploitation by combining current individual with best and random difference vectors.
- Parameters:
F (float, default=0.8) – Mutation factor (differential weight)
Notes
This strategy provides a good balance between DE/rand/1 and DE/best/1, often performing well on a wide range of problems.
- class pyrade.operators.mutation.DErand2(F=0.8)[source]
Bases:
MutationStrategyDE/rand/2: v = x_r1 + F * (x_r2 - x_r3) + F * (x_r4 - x_r5)
More exploratory strategy using two difference vectors. Provides greater diversity but may converge slower.
- Parameters:
F (float, default=0.8) – Mutation factor (differential weight)
Notes
Uses more difference vectors for increased exploration. Good for highly multimodal problems but requires larger populations.
- class pyrade.operators.mutation.DEbest2(F=0.8)[source]
Bases:
MutationStrategyDE/best/2: v = x_best + F * (x_r1 - x_r2) + F * (x_r3 - x_r4)
Highly exploitative strategy using best individual as base with two difference vectors. Fast convergence but risk of premature convergence.
- Parameters:
F (float, default=0.8) – Mutation factor (differential weight)
Notes
More aggressive than DE/best/1. Good for unimodal functions but requires careful parameter tuning for multimodal problems.
- class pyrade.operators.mutation.DEcurrentToRand1(F=0.8, K=0.5)[source]
Bases:
MutationStrategyDE/current-to-rand/1: v = x_i + K * (x_r1 - x_i) + F * (x_r2 - x_r3)
Combines current vector with random vector plus difference vector. More exploratory than current-to-best.
- Parameters:
Notes
Provides diversity through random direction. Good balance between exploration and maintaining population structure.
- class pyrade.operators.mutation.DERandToBest1(F=0.8)[source]
Bases:
MutationStrategyDE/rand-to-best/1: v = x_r1 + F * (x_best - x_r1) + F * (x_r2 - x_r3)
Direction from random vector toward best, plus random difference. Balances exploration from random base with exploitation toward best.
- Parameters:
F (float, default=0.8) – Mutation factor (differential weight)
Notes
Less greedy than DE/best/1 but still directed toward best solution. Good for problems where premature convergence is a concern.
- class pyrade.operators.mutation.DErand1EitherOr(F=0.8, p_F=0.5)[source]
Bases:
MutationStrategyDE/rand/1/either-or: v = x_r1 + F_i * (x_r2 - x_r3)
Uses probabilistic choice of scaling factor F_i which is either F or 0.5*F based on probability p_F (typically 0.5).
- Reference:
Price, K. V., Storn, R. M., & Lampinen, J. A. (2006). Differential Evolution: A Practical Approach to Global Optimization. Springer Science & Business Media.
- Parameters:
Notes
This strategy adds randomness in the scaling factor which can help maintain diversity. Each difference vector independently chooses between F and 0.5*F.
- class pyrade.operators.mutation.LevyFlightMutation(beta=1.5, scale=0.01)[source]
Bases:
MutationStrategyLévy flight-based mutation: DE/rand/1 with Lévy flight step sizes.
Uses Lévy flight random walk for generating step sizes, which provides heavy-tailed distribution beneficial for exploration. Lévy flights consist of many small steps with occasional large jumps, mimicking optimal foraging patterns found in nature.
Formula: v = x_r1 + L(β) * (x_r2 - x_r3) where L(β) is a Lévy flight step size with stability parameter β
- Parameters:
Notes
Lévy flight mutation is useful for: - Escaping local optima through large jumps - Maintaining good local search through small steps - Multimodal optimization problems - Exploration-exploitation balance
The Mantegna method is used to generate Lévy flight samples efficiently.
References
Yang, X. S., & Deb, S. (2009). Cuckoo search via Lévy flights. In 2009 World congress on nature & biologically inspired computing.
Examples
>>> mutation = LevyFlightMutation(beta=1.5, scale=0.01) >>> mutation = LevyFlightMutation(beta=1.0) # Cauchy-like
Crossover Strategies
Crossover strategies for Differential Evolution.
This module provides crossover strategies with fully vectorized implementations for high performance.
- class pyrade.operators.crossover.CrossoverStrategy[source]
Bases:
ABCAbstract base class for crossover strategies.
All crossover strategies should inherit from this class and implement the apply() method.
- abstractmethod apply(population, mutants)[source]
Apply crossover between population and mutants.
- Parameters:
population (ndarray, shape (pop_size, dim)) – Target vectors
mutants (ndarray, shape (pop_size, dim)) – Mutant vectors
- Returns:
trials – Trial vectors
- Return type:
ndarray, shape (pop_size, dim)
- class pyrade.operators.crossover.BinomialCrossover(CR=0.9)[source]
Bases:
CrossoverStrategyBinomial crossover: u_ij = v_ij if rand() <= CR or j == j_rand, else x_ij
Most common crossover in DE. Each dimension is independently crossed with probability CR.
- Parameters:
CR (float, default=0.9) – Crossover probability (0 <= CR <= 1)
Notes
Higher CR values lead to more exploitation (more from mutant), lower CR values lead to more exploration (more from parent). At least one dimension is always crossed over to ensure the trial differs from the target.
- class pyrade.operators.crossover.ExponentialCrossover(CR=0.9)[source]
Bases:
CrossoverStrategyExponential crossover: copies contiguous segment from mutant.
Alternative to binomial crossover. Copies a contiguous segment of dimensions from the mutant vector.
- Parameters:
CR (float, default=0.9) – Crossover probability (0 <= CR <= 1)
Notes
Exponential crossover tends to preserve building blocks better than binomial crossover. The length of the copied segment follows a geometric distribution with parameter CR.
- class pyrade.operators.crossover.UniformCrossover[source]
Bases:
CrossoverStrategyUniform crossover: each dimension independently with probability 0.5.
A simple crossover strategy where each dimension has equal probability of coming from either parent or mutant.
Notes
This is a special case of binomial crossover with CR=0.5, but ensures at least one dimension crosses over.
- class pyrade.operators.crossover.ArithmeticCrossover(alpha=0.5, adaptive=False)[source]
Bases:
CrossoverStrategyArithmetic crossover: weighted linear combination of parent and mutant.
Creates trial vectors as a weighted average: trial = alpha * mutant + (1-alpha) * parent This creates offspring that lie on a line between parent and mutant vectors.
- Parameters:
Notes
Arithmetic crossover is useful for: - Real-valued optimization (continuous domains) - Maintaining feasibility when parents are feasible - Smoother exploration of search space - Better preservation of numerical properties
Examples
>>> crossover = ArithmeticCrossover(alpha=0.5) # Equal blending >>> crossover = ArithmeticCrossover(alpha=0.7, adaptive=True) # Adaptive
- class pyrade.operators.crossover.ThreePointCrossover[source]
Bases:
CrossoverStrategyThree-point crossover: exchanges three segments between parent and mutant.
Randomly selects three crossover points and alternates between parent and mutant vectors. This creates more diverse offspring than single-point crossover.
Process: 1. Select three random positions 2. Segment: [0:p1] from one, [p1:p2] from other, [p2:p3] from first, [p3:] from other
- Parameters:
None
Notes
Three-point crossover is useful for: - Maintaining building blocks of intermediate size - More diversity than two-point crossover - Better mixing of parent and mutant characteristics - Discrete optimization problems
The crossover ensures good mixing while preserving some contiguous segments from both parents.
Examples
>>> crossover = ThreePointCrossover() >>> trials = crossover.apply(population, mutants)
Selection Strategies
Selection strategies for Differential Evolution.
This module provides selection strategies with fully vectorized implementations for high performance.
- class pyrade.operators.selection.SelectionStrategy[source]
Bases:
ABCAbstract base class for selection strategies.
All selection strategies should inherit from this class and implement the apply() method.
- abstractmethod apply(population, fitness, trials, trial_fitness)[source]
Select survivors for next generation.
- Parameters:
population (ndarray, shape (pop_size, dim)) – Current population
fitness (ndarray, shape (pop_size,)) – Current fitness
trials (ndarray, shape (pop_size, dim)) – Trial vectors
trial_fitness (ndarray, shape (pop_size,)) – Trial fitness
- Returns:
new_population (ndarray, shape (pop_size, dim)) – Selected population
new_fitness (ndarray, shape (pop_size,)) – Selected fitness
- class pyrade.operators.selection.GreedySelection[source]
Bases:
SelectionStrategyGreedy selection: keep trial if better, else keep target.
Standard DE selection. For minimization problems, selects the individual with lower fitness value.
Notes
This is the most common selection strategy in DE, ensuring the population never degrades (monotonic improvement).
- class pyrade.operators.selection.TournamentSelection(tournament_size=2)[source]
Bases:
SelectionStrategyTournament selection: select winner from random tournament.
Selects the best individual from a random subset of the population. Can add diversity compared to greedy selection.
- Parameters:
tournament_size (int, default=2) – Number of individuals in each tournament
Notes
Larger tournament sizes increase selection pressure. Tournament size of 2 is most common.
- class pyrade.operators.selection.ElitistSelection(elite_size=1)[source]
Bases:
SelectionStrategyElitist selection: always preserve best individuals.
Combines greedy selection with elitism to ensure the absolute best individuals are never lost.
- Parameters:
elite_size (int, default=1) – Number of elite individuals to preserve
Notes
Elite individuals are guaranteed to survive to the next generation, regardless of their trial performance.