Files
optimiz-rs/docs/source/algorithms/differential_evolution.md
T
2026-02-09 18:31:14 +01:00

210 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Differential Evolution
**Differential Evolution (DE)** is a powerful evolutionary algorithm for global optimization of continuous, non-linear, non-convex functions. It's particularly effective for multimodal optimization landscapes.
## Algorithm Overview
DE works by maintaining a **population** of candidate solutions and iteratively improving them through:
1. **Mutation**: Create mutant vectors by combining existing solutions
2. **Crossover**: Mix mutant with target vector
3. **Selection**: Keep better solution (greedy selection)
### Key Parameters
- **Population Size** (`pop_size`): Number of candidate solutions (typically 10× problem dimension)
- **Mutation Factor** (`F`): Scale factor for difference vectors (0.5-1.0)
- **Crossover Rate** (`CR`): Probability of using mutant component (0.0-1.0)
- **Strategy**: Mutation/crossover strategy (see below)
## Strategies
OptimizR implements 5 DE strategies:
### 1. `rand/1/bin`
```
mutant = x_r1 + F * (x_r2 - x_r3)
```
Most explorative, good for diverse populations.
### 2. `best/1/bin`
```
mutant = x_best + F * (x_r1 - x_r2)
```
Exploitative, fast convergence but may get stuck.
### 3. `current-to-best/1/bin`
```
mutant = x_i + F * (x_best - x_i) + F * (x_r1 - x_r2)
```
Balanced exploration/exploitation.
### 4. `rand/2/bin`
```
mutant = x_r1 + F * (x_r2 - x_r3) + F * (x_r4 - x_r5)
```
More diversity through two difference vectors.
### 5. `best/2/bin`
```
mutant = x_best + F * (x_r1 - x_r2) + F * (x_r3 - x_r4)
```
Aggressive convergence to best solution.
## Usage Example
```python
import numpy as np
from optimizr import differential_evolution
def rastrigin(x):
A = 10
return A * len(x) + sum(x**2 - A * np.cos(2 * np.pi * x))
best_x, best_fx = differential_evolution(
objective_fn=rastrigin,
bounds=[(-5.12, 5.12)] * 10,
strategy="best1",
popsize=20,
maxiter=500,
adaptive=True,
)
print(f"Best fitness: {best_fx:.6f}")
print(f"Best solution: {best_x}")
```
## Advanced Features
### Adaptive control (jDE, SHADE-ready)
```python
de = DifferentialEvolution(
bounds=[(-5, 5)] * 20,
adaptive=True, # jDE by default
tau_F=0.1,
tau_CR=0.1,
)
```
- jDE is enabled when `adaptive=True` (self-adapts F, CR).
- SHADE and L-SHADE are implemented in Rust (`shade.rs`) and ready to be wired into the Python API in an upcoming release; see `SHADE_IMPLEMENTATION.md` for details.
### Parallel evaluation (Rust-only objectives)
For pure Rust benchmarks or when you avoid Python callbacks, you can turn on data-parallel evaluation (Rayon-based) via the Rust entry point:
```python
from optimizr import parallel_differential_evolution_rust
best = parallel_differential_evolution_rust(
objective_name="rastrigin", # sphere, rosenbrock, ackley, griewank
bounds=[(-5, 5)] * 20,
maxiter=500,
parallel=True,
)
```
This yields 10100× speedups on multi-core for built-in objectives (no GIL contention).
### Constraint handling
```python
def constraints(x):
"""Return array of constraint violations (> 0 means violated)"""
return np.array([
x[0]**2 + x[1]**2 - 1, # x0^2 + x1^2 <= 1
x[0] + x[1] - 2 # x0 + x1 <= 2
])
de = DifferentialEvolution(
bounds=[(-5, 5)] * 2,
constraints=constraints,
penalty_factor=1000
)
```
## Performance Tips
1. **Population Size**: Start with `10 × dim`, increase if stuck
2. **F parameter**:
- Low (0.4-0.6): Fine-tuning, local search
- High (0.8-1.0): Exploration, escape local minima
3. **CR parameter**:
- Low (0.1-0.3): Separable problems
- High (0.9-1.0): Non-separable, coupled variables
4. **Strategy Selection**:
- Unknown landscape → `rand/1/bin` or `rand/2/bin`
- Smooth, unimodal → `best/1/bin`
- Multimodal, deceptive → `current-to-best/1/bin`
### Pipeline integrations
- **Time-series workflows**: couple DE with `timeseries_utils` (rolling Hurst/half-life) to optimize strategy thresholds.
- **Grid search fallback**: for separable problems, try `grid_search` first; switch to DE when interactions matter.
## Benchmarks
Performance on standard test functions (10D, 500 iterations):
| Function | Success Rate | Avg Time | Best Fitness |
|----------|--------------|----------|--------------|
| Sphere | 100% | 12ms | 1e-12 |
| Rosenbrock | 98% | 18ms | 3e-6 |
| Rastrigin | 87% | 22ms | 0.02 |
| Ackley | 95% | 15ms | 2e-8 |
*Compared to SciPy `differential_evolution`: 50-80× faster*
## Mathematical Details
### Mutation Operator
For strategy `rand/1/bin`:
$$
\mathbf{v}_{i,g} = \mathbf{x}_{r_1,g} + F \cdot (\mathbf{x}_{r_2,g} - \mathbf{x}_{r_3,g})
$$
Where:
- $\mathbf{v}_{i,g}$: Mutant vector for individual $i$ at generation $g$
- $\mathbf{x}_{r_j,g}$: Randomly selected individuals ($r_1 \neq r_2 \neq r_3 \neq i$)
- $F \in [0, 2]$: Mutation scaling factor
### Crossover Operator
Binomial crossover:
$$
u_{i,j,g} = \begin{cases}
v_{i,j,g} & \text{if } \text{rand}(0,1) < CR \text{ or } j = j_{rand} \\\\
x_{i,j,g} & \text{otherwise}
\end{cases}
$$
Ensures at least one component from mutant.
### Selection Operator
Greedy selection:
$$
\mathbf{x}_{i,g+1} = \begin{cases}
\mathbf{u}_{i,g} & \text{if } f(\mathbf{u}_{i,g}) \leq f(\mathbf{x}_{i,g}) \\\\
\mathbf{x}_{i,g} & \text{otherwise}
\end{cases}
$$
## References
1. Storn, R., & Price, K. (1997). *Differential evolutiona simple and efficient heuristic for global optimization over continuous spaces*. Journal of global optimization, 11(4), 341-359.
2. Das, S., & Suganthan, P. N. (2011). *Differential evolution: A survey of the state-of-the-art*. IEEE transactions on evolutionary computation, 15(1), 4-31.
3. Brest, J., et al. (2006). *Self-adapting control parameters in differential evolution: A comparative study on numerical benchmark problems*. IEEE transactions on evolutionary computation, 10(6), 646-657.
## See Also
- [API Reference](../api/differential_evolution.md)
- [Jupyter Tutorial](https://github.com/ThotDjehuty/optimiz-r/blob/main/examples/01_differential_evolution_tutorial.ipynb)
- [Benchmarks](../benchmarks.md)