pymetaheuristics¶
Metaheuristics for optimization problems in plain Python, with no dependencies. You describe the problem: how to make a solution, how to score it, which solutions are allowed, and whether to minimize or maximize. Then you hand it to a heuristic, which returns the best solution it found.
Metaheuristics are a good fit when the search space is too large to enumerate and no exact solver suits the problem: combinatorial problems (routing, packing, scheduling, assignment) or black-box objectives. They give good solutions quickly, but they don't prove those solutions are optimal.
The library ships with:
- Genetic Algorithm:
genetic_algorithm(), a population-based search with pluggable selection, crossover and mutation. - Simulated Annealing:
simulated_annealing(), a single-trajectory search with pluggable neighborhoods and cooling schedules. - A benchmark suite of Knapsack, TSP and continuous problems with known optima.
Every heuristic is a plain function with the same shape, so you can swap algorithms without touching the problem. This documentation describes the API as of 0.2.
Install¶
Requires Python 3.12+.
Quickstart¶
Find a short closed tour through five points:
import math
from pymetaheuristics.core import Problem, max_iterations
from pymetaheuristics.simulated_annealing import simulated_annealing
cities = [(0, 0), (0, 2), (3, 2), (3, 0), (1, 1)]
def tour_length(tour):
return sum(math.dist(cities[tour[i - 1]], cities[tour[i]])
for i in range(len(tour)))
problem = Problem(
generate=lambda rng: rng.sample(range(len(cities)), len(cities)),
evaluate=tour_length,
) # direction defaults to Direction.MINIMIZE
result = simulated_annealing(problem, stop=max_iterations(500), rng=0)
print(result.best_solution, round(result.best_value, 3))
Switching heuristics changes only the call:
How well does it work?¶
Every heuristic against random search on the benchmark suite, with the same budget of 2000 evaluations over 20 seeds (details):

On TSP all three heuristics find the optimum on every seed and on the sphere the GA and SA close over 99.7% of random search's gap, while random search stays far off. Rastrigin is hard for all of them with this budget. A full run takes about 10-30 ms.
What can I do?¶
| I want to... | Go to |
|---|---|
| describe my problem, minimizing or maximizing | Problem and direction |
| forbid invalid solutions (reject, repair, penalty) | Constraints |
| stop by iterations, evaluations, time or target value | Stopping |
| use a built-in neighborhood, selection, crossover or mutation | Operators |
| search with a population | Genetic Algorithm |
| search with one moving solution | Simulated Annealing |
| read the best solution and plot convergence | Results and history |
| get the same run twice | Reproducibility |
| see complete programs | Worked examples |
| write my own operator, stop or heuristic | Extending |
| test against problems with known optima | Benchmark suite |
| look up a function | Reference |
Where next¶
- Tutorial: problems, directions, constraints, both heuristics, results and history.
- Worked examples: Knapsack and TSP from start to finish.
- Extending: write your own operator or heuristic.
- Reference: the API, from the docstrings.
- Architecture: how the core is put together.
- Release notes: what changed between versions.