Pure-numpy genetic algorithm framework for single-objective (GA) and multi-objective (NSGA-II) optimization
Project description
ctrl-freak
An extensible genetic algorithm framework for single and multi-objective optimization, built on pure numpy.
Maintenance Status
๐ข Active Development
This repository is part of an ongoing project and actively maintained.
Installation
uv add ctrl-freak
Quick Start
import numpy as np
from ctrl_freak import nsga2, ga
# === Multi-Objective: NSGA-II ===
def init(rng):
return rng.uniform(0, 1, size=5)
def evaluate_multi(x):
f1 = x[0]
f2 = 1 - np.sqrt(x[0]) + x[1:]@x[1:]
return np.array([f1, f2])
def crossover(p1, p2):
return (p1 + p2) / 2
def mutate(x):
return np.clip(x + np.random.normal(0, 0.1, size=x.shape), 0, 1)
result = nsga2(
init=init,
evaluate=evaluate_multi,
crossover=crossover,
mutate=mutate,
pop_size=100,
n_generations=50,
seed=42,
)
# Extract Pareto front
pareto_front = result.pareto_front
print(f"Found {len(pareto_front)} Pareto-optimal solutions")
# === Single-Objective: Standard GA ===
def evaluate_single(x):
return float(np.sum(x ** 2)) # Sphere function
result = ga(
init=init,
evaluate=evaluate_single,
crossover=crossover,
mutate=mutate,
pop_size=100,
n_generations=100,
seed=42,
)
print(f"Best fitness: {result.best[1]:.6f}")
Documentation
- API Usage Guide โ Installation, examples, working with results
- User Contracts โ Function signatures and responsibilities
Design Philosophy
- Pure numpy for performance
- Functional style with immutable data structures
- User thinks about individuals, framework handles vectorization via
lift() - Fail fast with eager validation
- Domain agnostic โ framework handles selection pressure, user handles constraints/bounds
- Extensible via pluggable selection and survival strategies
Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ User Domain Layer โ
โ init(), evaluate(), crossover(), mutate() โ
โ (per-individual, user-defined) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ lift()
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Algorithm Layer โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โ โ nsga2() โ โ ga() โ โ
โ โ multi-obj โ โ single-obj โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โ โ โ โ
โ โโโโโโโโโโฌโโโโโโโโโโ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Pluggable Strategies โ โ
โ โ Selection: crowded, tournament, roulette โ โ
โ โ Survival: nsga2, truncation, elitist โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Primitives (pure functions) โ
โ non_dominated_sort(), crowding_distance(), dominates() โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
API Reference
Algorithms
# Multi-objective optimization
nsga2(init, evaluate, crossover, mutate, pop_size, n_generations,
seed=None, callback=None, select='crowded', survive='nsga2',
n_workers=1) -> NSGA2Result
# Single-objective optimization
ga(init, evaluate, crossover, mutate, pop_size, n_generations,
seed=None, callback=None, select='tournament', survive='elitist',
n_workers=1) -> GAResult
User Function Contracts
| Function | Signature | Description |
|---|---|---|
init |
(rng) -> (n_vars,) |
Initialize one random individual |
evaluate |
(n_vars,) -> (n_obj,) or float |
Compute objectives (minimization) |
crossover |
(n_vars,), (n_vars,) -> (n_vars,) |
Combine two parents into one child |
mutate |
(n_vars,) -> (n_vars,) |
Perturb an individual |
Result Types
NSGA2Result โ Multi-objective optimization result:
population: Populationโ Final populationrank: np.ndarrayโ Pareto front ranks(n,)where 0 = optimalcrowding_distance: np.ndarrayโ Diversity measure(n,)pareto_front: Populationโ Property returning rank-0 individualsgenerations: intโ Generations completedevaluations: intโ Total evaluations
GAResult โ Single-objective optimization result:
population: Populationโ Final populationfitness: np.ndarrayโ Fitness values(n,)best: tuple[np.ndarray, float]โ Property returning (best_x, best_fitness)generations: intโ Generations completedevaluations: intโ Total evaluations
Data Structures
Population โ Immutable collection of solutions:
x: np.ndarrayโ Decision variables(n, n_vars)objectives: np.ndarray | Noneโ Objective values(n, n_obj)
Selection Strategies
| Name | Function | Use Case |
|---|---|---|
'crowded' |
crowded_tournament() |
NSGA-II (rank + crowding) |
'tournament' |
fitness_tournament() |
GA (fitness-based) |
'roulette' |
roulette_wheel() |
GA (fitness-proportionate) |
Survival Strategies
| Name | Function | Use Case |
|---|---|---|
'nsga2' |
nsga2_survival() |
NSGA-II (fronts + crowding) |
'truncation' |
truncation_survival() |
Keep best k |
'elitist' |
elitist_survival() |
Preserve elite parents |
Primitives
| Function | Description |
|---|---|
dominates(a, b) |
Check if a Pareto-dominates b |
dominates_matrix(objectives) |
Pairwise dominance matrix |
non_dominated_sort(objectives) |
Assign Pareto front ranks |
crowding_distance(front) |
Compute crowding distances for one front |
Benchmarks
Tested against Pymoo and DEAP on ZDT test problems (100 pop, 250 generations, 10 seeds):
| Problem | ctrl-freak | Pymoo | DEAP |
|---|---|---|---|
| ZDT1 | 0.8653 ยฑ 0.0011 | 0.8241 ยฑ 0.0255 | 0.8698 ยฑ 0.0002 |
| ZDT2 | 0.5320 ยฑ 0.0017 | 0.4764 ยฑ 0.0182 | 0.5363 ยฑ 0.0002 |
| ZDT3 | 1.3224 ยฑ 0.0008 | 1.2836 ยฑ 0.0123 | 1.3275 ยฑ 0.0002 |
ctrl-freak matches DEAP-level hypervolume on ZDT1-3 with low variance. See full benchmark results.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ctrl_freak-0.1.0.tar.gz.
File metadata
- Download URL: ctrl_freak-0.1.0.tar.gz
- Upload date:
- Size: 25.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93d81208b6f46c5898dceb4cd8f84d759a02c7f6f3d9fbaed1824ae924dc9708
|
|
| MD5 |
740eca747933f86953826c62624e581c
|
|
| BLAKE2b-256 |
57931b74e39f2ddd0a67181947cd3cb861aff40b25a0a3ea39eacb7a8ceb894c
|
File details
Details for the file ctrl_freak-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ctrl_freak-0.1.0-py3-none-any.whl
- Upload date:
- Size: 38.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
edb053a1b9bc4bba2397feb11d71326d5a0e999ad30dcc911aaa1d006312d842
|
|
| MD5 |
bc0f48628a255832fdeae5a2950e6efb
|
|
| BLAKE2b-256 |
5f3107736be816a8a999c97fd1a58fbd3b9cfe582cb2cdfcfc29fab45486a70b
|