puggles
Fast multi-objective evolutionary optimization for Python — NSGA-II and NSGA-III, with a Rust core. Roughly 7–8× faster than pymoo and 20–30× faster than DEAP and platypus at equal solution quality.
pip install puggles
Prebuilt wheels for Linux, macOS, and Windows; Python 3.9+. No Rust toolchain needed.
Quick start
import puggles as pg
# ZDT1: two conflicting objectives over 10 variables in [0, 1].
def zdt1(x):
g = 1 + 9 * sum(x[1:]) / (len(x) - 1)
return [x[0], g * (1 - (x[0] / g) ** 0.5)]
problem = pg.Problem(
solution_length=10,
number_of_objectives=2,
solution_data_types=[pg.Real(0.0, 1.0)] * 10,
objective_function=zdt1, # must return a LIST, one entry per objective
direction=[-1, -1], # -1 = minimize, 1 = maximize
)
ga = pg.NSGAII(problem, population_size=100, seed=42)
ga.run(10_000) # budget in objective-function evaluations
for s in ga.get_archive(): # the Pareto front
print(s.variables, s.objectives)
Benchmarks
ZDT1, population 100, 10,000 evaluations, Apple M3. IGD lower is better — all libraries converge to the same quality, so the difference is pure algorithm overhead.
| library | ms / run | IGD |
|---|---|---|
| puggles | 31.8 | 0.0051 |
| pymoo | 215.4 | 0.0045 |
| DEAP | 843.4 | 0.0048 |
| platypus | 1062.1 | 0.0108 |
On DTLZ2 (3 objectives), NSGAIII reaches IGD 0.011 — the best of any library measured,
against pymoo's 0.076.
Features
- NSGA-II and NSGA-III (reference-point based; prefer it for 3+ objectives)
- Real, Integer, and Binary decision variables, mixable in one problem
- Constraints — objective bounds and decision-variable
g(x) <= 0 - Batch objectives —
batch_objective_function=fevaluates a whole population per call, amortizing the GIL. ~1.8× on an expensive objective; a wash on a cheap one. Works with bothNSGAIIandNSGAIII. - Permutation encoding —
permutation=Truefor ordering problems (TSP, scheduling); uses order crossover and swap mutation so solutions stay valid permutations. - Checkpoint & resume —
ga.save_state()returns JSON,ga.load_state(s)restores it, so long runs survive a restart. - Front-quality metrics —
hypervolume_2d,igd,spacing, andrun_until_hv_converged(...)to stop when the front stops improving instead of at a fixed budget. - Island model —
run_island_model(...)runs independent populations in parallel and merges their fronts (native Rust objectives only; the GIL would serialize Python callables). - Reproducible runs —
seed=42fixes the initial population, crossover, mutation, and selection, so a run repeats exactly. Omit it for fresh randomness each time. - GPU evaluation via
GpuProblemand a WGSL compute shader (experimental) - Clear errors — invalid bounds or configuration raise
ValueError, not a Rust panic. - Built-in DTLZ1–7 benchmark problems
Permutation example
import puggles as pg
POS = [0.0, 9.0, 3.0, 7.0, 1.0, 5.0, 8.0, 2.0]
tour = lambda x: [sum(abs(POS[int(a)] - POS[int(b)]) for a, b in zip(x, x[1:]))]
problem = pg.Problem(8, 1, [pg.Integer(0, 7)] * 8, tour, permutation=True)
ga = pg.NSGAII(problem, population_size=40, seed=5)
ga.run(6000)
best = min(ga.get_archive(), key=lambda s: s.objectives[0])
print(best.objectives[0], [int(v) for v in best.variables])
Reproducibility
A genetic algorithm is randomised: without a seed, two runs of identical code give different answers (on ZDT1, roughly 10% apart in IGD). Pass a seed to make a run exactly repeatable — essential for publishing a result, writing a regression test, or comparing two parameter settings without measuring noise.
a = pg.NSGAII(problem, seed=42); a.run(10_000)
b = pg.NSGAII(problem, seed=42); b.run(10_000)
# a and b produce identical fronts, down to the last bit
Seeding applies to NSGAIII too. Use it with execution_mode="sequential": multithreaded runs
interleave evaluations non-deterministically, so they are not reproducible even when seeded.
Many objectives
ga = pg.NSGAIII(problem, divisions=12, seed=42) # population derived from the reference points
ga.run(20_000)
Tuning operators
ga = pg.NSGAII(
problem,
population_size=100,
crossover_config=pg.CrossoverConfig(real_crossover="sbx", sbx_distribution_index=20.0),
mutation_config=pg.MutationConfig(real_mutation="polynomial"), # probability=None -> 1/n
)
Leave probability at None unless you have a reason: it defaults to the conventional 1/n
per-gene rate. A rate of 1.0 replaces the whole genome every generation, which is random
search, not evolution.
Status
The NSGA-II core across all three encodings is well tested and benchmarked. The GPU evaluator is experimental and untested in CI. One Python-callable problem may be optimized at a time per process — concurrent GAs over different Python objectives in threads are not supported.
Links
- Source, Rust API, and full guide: https://github.com/Entropy314/puggles
- Issues: https://github.com/Entropy314/puggles/issues
License
MIT OR Apache-2.0
Metadata
Release files for puggles 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| puggles-0.2.0.tar.gz | 107.7 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| puggles-0.2.0-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| puggles-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| puggles-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| puggles-0.2.0-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details |
| puggles-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 2.5 MB
Release files / puggles-0.2.0.tar.gz
| Download URL | puggles-0.2.0.tar.gz |
|---|---|
| Size | 107.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c4be6a75eed1daa0dba227e5dba85e8bff5d0b967b8717c7d9c843610f1fb3b7
|
|
BLAKE2b-256 checksum How to use checksums |
42915674922f7639933e017a5857d6ac46a255a6c7a5de231d7dd368d5d7cbf4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / puggles-0.2.0-cp39-abi3-win_amd64.whl
| Download URL | puggles-0.2.0-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 398.6 kB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
8f3152d9e8bd33f292bd6838dc42b37ccf65e9eb78894339e8b4c50abe74754a
|
|
BLAKE2b-256 checksum How to use checksums |
da14843ebde7f79c3b0e3b2291be71538306ddbaefcb6a7bdfa10e8896fe87ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / puggles-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | puggles-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 525.3 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
500d624b07a6566b4be998174034920cadf6581c9b6ee4d45a25835c7a553551
|
|
BLAKE2b-256 checksum How to use checksums |
25e83a36adedb512a313dc1b5b8aeed101bb064fa60897511c3e4a30e1996a85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / puggles-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | puggles-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 512.6 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
a7ed1b3c337fdaac5c017308cc447c60e9e39191a882600f607ab89d3f8fda02
|
|
BLAKE2b-256 checksum How to use checksums |
0bb4af0d93c0d0cb139533ab0ea4ff57b283822db2236a77ed248c4b30c0a438
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / puggles-0.2.0-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | puggles-0.2.0-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 473.2 kB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
107ac5c02d394aea8f40e07353215aabb761bd6caa263fa933544c4dcc4b0c1b
|
|
BLAKE2b-256 checksum How to use checksums |
a262ae7b23afd21154bb35d04725534729648a5c10e9f1363587e01741eec63e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / puggles-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | puggles-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 496.3 kB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
384ef798e26efa5c116cbaa1e91dba656065cc5575558cfe9ea4af6b88a74e86
|
|
BLAKE2b-256 checksum How to use checksums |
bc7cb0e727f993eed3c2ad1c67f2d43b55394078cc1c3ffa99f06f87ea9b6d26
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|