Lightweight Covariance Matrix Adaptation Evolution Strategy (CMA-ES)
cmaes is a lightweight Python library providing an implementation of the Covariance Matrix Adaptation Evolution Strategy (CMA-ES) for numerical optimization. It offers a simple "ask-and-tell" interface and has expanded to include various advanced CMA-ES variants such as CatCMA, CMAwM, and COMO-CatCMAwM, catering to mixed-variable and multi-objective optimization problems. The library is actively maintained, currently at version 0.13.0, with frequent updates introducing new algorithms and features.
Warnings
- breaking Python 3.6 support was dropped in `v0.9.1`.
- gotcha The library offers numerous specialized optimizers (e.g., `CatCMAwM`, `COMOCatCMAwM`, `CMAwM`) for specific problem types beyond continuous, single-objective optimization.
- gotcha The core `CMA` class is designed for continuous optimization problems. Using it directly for problems involving integer, categorical, or mixed variables, or for multi-objective optimization, may lead to suboptimal performance or incorrect results.
Install
-
pip install cmaes -
conda install -c conda-forge cmaes
Imports
- CMA
from cmaes import CMA
- CatCMAwM
from cmaes import CatCMAwM
- COMOCatCMAwM
from cmaes import COMOCatCMAwM
Quickstart
import numpy as np
from cmaes import CMA
def quadratic(x1, x2):
# Objective function to minimize
return (x1 - 3) ** 2 + (10 * (x2 + 2)) ** 2
if __name__ == "__main__":
# Initialize CMA optimizer with an initial mean and standard deviation
optimizer = CMA(mean=np.zeros(2), sigma=1.3)
print("Starting CMA-ES optimization...")
for generation in range(50):
solutions = []
# Ask for new candidate solutions
for _ in range(optimizer.population_size):
x = optimizer.ask()
value = quadratic(x[0], x[1])
solutions.append((x, value))
# Print the best value found in the current generation
# (Note: CMA-ES updates distribution based on all solutions, not just the best)
print(f"Generation #{generation+1}: Best value = {min(s[1] for s in solutions):.4f}")
# Tell the optimizer the evaluated solutions and their values
optimizer.tell(solutions)
print(f"\nOptimization finished. Final mean of the search distribution: {optimizer.mean}")