Native Rust examples
The root fcmaes-examples crate contains the compact binaries documented
below. Larger application studies are isolated under
tutorials/, including validation-aware SmartCore
hyperparameter tuning and the room-ventilation tutorial’s purpose-built Rust
flow backend, held-out pollutant releases, MODE, MAP-Elites, and resolution
evidence. The neural-controller tutorial additionally provides a direct
PGPE/CR-FM-NES policy-search comparison with randomized native Rust rollouts.
Reusable patterns for turning optimizer vectors into integer, categorical,
subset, permutation, partition, and schedule decisions are collected in the
combinatorial encoding cookbook. Its tested
reference helpers live in
examples/src/encoding.rs.
Binaries
The fcmaes-examples crate provides:
| Binary | Execution model | Optimizer or purpose |
|---|---|---|
gtop-examples | Independent basic retry | 40% DE, then 60% active CMA-ES |
gtop-advexamples | Coordinated advanced retry | 40% DE, then 60% active CMA-ES |
benchmark-gtop | Repeated coordinated-retry experiments | GTOP tutorial-style statistics and raw results |
benchmark-biteopt-gtop | Repeated basic-retry experiments | BiteOpt or DE→CMA statistics and raw results |
mazda-mo | MODE | Constrained mass/common-parts Pareto search |
mazda-qd | CVT-MAP-Elites, optional Diversifier | Mazda behavior archive |
trading | MODE and CVT-MAP-Elites | Four-stock EMA/SMA strategy search |
material-flow-planning | BiteOpt | Native 24-hour factory simulation and throughput measurement |
buckingham-pi | Enumeration, BiteOpt retry, and MODE | Native dimensionless-group analysis and continuous exponent search |
uav-task-assignment | BiteOpt retry and MODE | Single- and multi-objective extended team-orienteering benchmark |
jobshop | BiteOpt | Flexible job-shop objective; optional Brandimarte .fjs input |
harvesting | BiteOpt | Job-shop with bounded machine deployment windows |
t-design | BiteOpt | Weighted spherical t-design using native harmonics |
scheduling | BiteOpt | Dyson-ring transfer scheduler; optional text/XZ input |
damp | BiteOpt | Controlled spring with exact segment propagation |
f8 | BiteOpt | F-8 bang-bang aircraft control with native DOPRI5 |
lotka | BiteOpt | Lotka-Volterra fox-control problem with native DOPRI5 |
Cargo uses these names because examples is also a reserved Cargo target
category.
Native objective ports
Seven compact application families have native Rust objective implementations.
Each binary accepts --evals, --batch, and --seed; the defaults are
20,000, 16, and 42. These small commands are useful smoke tests:
cargo run --release -p fcmaes-examples --bin jobshop -- --evals 2000
cargo run --release -p fcmaes-examples --bin harvesting -- --evals 2000 2
cargo run --release -p fcmaes-examples --bin t-design -- --evals 2000 10 4
cargo run --release -p fcmaes-examples --bin scheduling -- --evals 2000
cargo run --release -p fcmaes-examples --bin damp -- --evals 2000 12
cargo run --release -p fcmaes-examples --bin f8 -- --evals 2000 6
cargo run --release -p fcmaes-examples --bin lotka -- --evals 2000
jobshop and harvesting use a small embedded flexible-shop instance when no
dataset is given. Supply any Brandimarte-format instance with --data; the
harvesting positional argument is the maximum number of active machines:
cargo run --release -p fcmaes-examples --bin jobshop -- \
--data /path/to/BrandimarteMk1.fjs
cargo run --release -p fcmaes-examples --bin harvesting -- \
--data /path/to/BrandimarteMk1.fjs 4
scheduling similarly embeds a deterministic transfer fixture. Its loader
accepts the original whitespace format in either plain text or XZ form:
cargo run --release -p fcmaes-examples --bin scheduling -- \
--data /path/to/tsin3000.60.xz
The scheduling module exposes the shaped scalar objective, true score, two-objective vector, and MAP-Elites descriptor ingredients. Job-shop exposes all three objectives, while harvesting adds the failure constraint. Other Rust programs can therefore use MODE or MAP-Elites directly even though these compact CLI drivers use scalar BiteOpt.
The numerical choices are intentional. t-design evaluates associated
Legendre functions with a stable recurrence including SciPy’s
Condon-Shortley phase. F-8 and Lotka-Volterra use an allocation-free adaptive
Dormand-Prince 5(4) integrator. The controlled spring has an exact solution on
each constant-control segment, which is faster and more accurate than
numerically integrating the same linear equation.
Unit tests compare fixed objective vectors against the original NumPy/SciPy
implementations. Loader tests are hermetic; release smoke tests also cover the
published Brandimarte Mk1 and both tsin3000.10.xz and tsin3000.60.xz
datasets when those optional files are present.
Mazda factory design
The Mazda benchmark has 222 discrete variables, five raw objectives, and 54 constraints. The example crate embeds the discrete decision table, three mass regressions, and 42 radial-basis constraint surfaces. The evaluator, constraint sign conversion, MODE, QD scalarization, archive management, and Pareto selection all execute in Rust. Shared response-surface training matrices are stored and evaluated once per group, and no external model files are required. See the Mazda data notice for provenance and the benchmark’s acknowledgement request.
Run the constrained MO example:
cargo run --release -p fcmaes-examples --bin mazda-mo -- \
--evaluations 500000 --popsize 768 --workers 16 --seed 42
Add --de-update to use MODE’s DE population update; the default is NSGA-II.
Progress reports the feasible offspring count, and final output lists up to 30
feasible Pareto points as mass and common-parts count. Each MODE population is
evaluated as an ordered parallel batch.
Run CVT-MAP-Elites with the published descriptors and penalty:
cargo run --release -p fcmaes-examples --bin mazda-qd -- \
--capacity 10000 --samples-per-niche 0 \
--generations 10000 --chunk-size 100 --workers 16 --seed 42
Use --iso-line for the Iso+LineDD emitter or append
--diversify-evaluations 1000000 for a CMA-based Diversifier phase. The
two-dimensional samples-per-niche=0 path uses a constant-time rectangular
niche index and avoids CVT setup. Set it to 20 to reproduce the Python sample’s
k-means CVT; setup then grows quadratically with archive capacity. Use a
smaller archive for a CVT smoke test:
cargo run --release -p fcmaes-examples --bin mazda-qd -- \
--capacity 64 --samples-per-niche 4 --generations 10 --chunk-size 16
For both Mazda binaries, --workers 1 is serial, a positive value requests
exactly that many cached worker threads, and --workers 0 uses available
parallelism. MAP-Elites and Diversifier candidates are evaluated concurrently;
archive updates are then applied in original candidate order, so changing the
worker count does not change a seeded result.
Trading strategy
The trading binary optimizes an EMA/SMA crossing strategy over NVDA, GOOGL,
AAPL, and MSFT. Defaults use adjusted daily closes from 2020 through 2025. A
matching snapshot is included under ticker_cache/, allowing a deterministic
run without network access:
cargo run --release -p fcmaes-examples --bin trading -- --offline
The command performs two searches:
- MODE minimizes one negative return factor per stock, subject to at most 12
signal-triggered trades per stock.
MO qualityis the best geometric mean of the four relative returns among feasible Pareto points. - MAP-Elites minimizes the negative geometric mean return while using the four
per-stock return factors as behavior descriptors.
QD qualityis the sum of archive returns divided by total archive capacity, so empty niches contribute zero and both quality and coverage matter.
Returns are relative to buying and holding the same stock over the period. The
program prints machine-readable CONFIG, MO, QD, and RESULT lines so
runs can be compared across compiler versions and optimizer settings.
Useful controls include --mo-evaluations, --qd-evaluations, --popsize,
--capacity, --chunk-size, --samples-per-niche, --seed, and --tickers.
Pass --offline to prohibit downloads when a cache is missing.
Material-flow-planning speed example
The material-flow objective simulates two machines, setup delays, and an eight-part FIFO for every second of a 24-hour production day. Its deliberately fine-grained 86,400-tick implementation is entirely native Rust. Run the objective workload and BiteOpt search with:
cargo run --release -p fcmaes-examples --bin material-flow-planning
The binary first evaluates a deterministic 256-point input sequence, then uses
the native BiteOpt implementation with a fixed seed, ask/tell batch size, and
256-evaluation budget. The fixed-workload checksum and optimizer result make
semantic drift immediately visible. OBJECTIVE and OPTIMIZE lines report
separate wall times and throughput. Override the workloads with
--benchmark-evaluations and --optimize-evaluations.
Buckingham–Pi dimensional analysis
The buckingham-pi binary implements its dimension-matrix analysis,
regression, validation, and optimization in Rust. It can enumerate
conventional repeating-variable bases, rank them using held-out data, search
continuous nullspace exponents with independent BiteOpt retries, or use MODE
to expose the trade-off among predictive quality, exponent simplicity, and
feature independence.
Run the complete two-group cylinder workflow with 16 workers:
cargo run --release -p fcmaes-examples --bin buckingham-pi -- \
--problem cylinder --mode all --groups 2 --samples 300 \
--workers 16 --retries 32 --evaluations 2000 \
--mo-evaluations 20000 --popsize 128 --seed 42
The example is a numerical Rust implementation, not a BuckinghamPy binding or symbolic unit parser. Its deterministic synthetic data use disjoint training and holdout PCG streams; replace them with measured or simulation data for a scientific application. See the Buckingham–Pi guide for its equations, safeguards, objectives, recorded validation result, catalog, and smaller mode-specific commands. Source attribution is in the Buckingham notice.
Multi-UAV task assignment
The uav-task-assignment binary ports the enhanced
Multi-UAV-Task-Assignment-Benchmark’s extended team-orienteering objective.
It generates the published small (5 UAVs/30 targets), medium (10/60), and
large (15/90) distributions without external files. The decision vector uses
vehicles - 1 route-separator keys plus one random key per target, ensuring
that each target appears exactly once in the decoded visit order.
The default command runs both formulations on the small preset:
cargo run --release -p fcmaes-examples --bin uav-task-assignment
- Single-objective mode maximizes collected reward with independent BiteOpt
retries.
--evaluationsis the budget per retry and--workerscontrols outer retry parallelism. - Multi-objective mode uses one coordinated MODE population to minimize
negative reward, maximum arrival time, and the benchmark energy proxy.
--mo-evaluationsis its total requested budget and the same--workersvalue controls ordered population evaluation.
A quick four-worker smoke run is:
cargo run --release -p fcmaes-examples --bin uav-task-assignment -- \
--mode both --evaluations 2000 --retries 4 \
--mo-evaluations 2048 --popsize 64 --workers 4 --seed 65
Use --size medium or --size large, or override --vehicles, --targets,
and --map-size independently. A 16-worker single-objective run matching the
benchmark’s two retries per worker and small per-retry budget is:
cargo run --release -p fcmaes-examples --bin uav-task-assignment -- \
--size small --mode single --workers 16 --retries 32 \
--evaluations 2000000 --depth 2 --seed 65
The native evaluator retains the enhanced benchmark’s strict arrival-horizon test and travel-energy formula. Rust seeds use PCG and therefore do not create the same instances as Python’s Mersenne Twister. See the provenance and compatibility notice.
Problem catalog
| CLI name | Display name | Dimension |
|---|---|---|
cassini1 | Cassini1 | 6 |
cassini2 | Cassini2 | 22 |
rosetta | Rosetta | 22 |
tandem | Tandem 6 | 18 |
messenger | Messenger reduced | 18 |
gtoc1 | GTOC1 | 8 |
messenger-full | Messenger full | 26 |
sagas | Sagas | 12 |
cassini1-minlp | Cassini1 MINLP with fixed sequence | 6 |
Problem matching ignores case and separators. Messenger Full also accepts
messenger_full, Messenger Full, and messfull. Omit --problem, or pass
--problem all, to run the complete catalog.
CLI options
Both binaries share the same parser:
| Option | Default | Meaning |
|---|---|---|
--problem NAME | all | Select one problem |
--retries N | 32 | Retry count per selected problem |
--evaluations N | 50,000 | Initial per-retry DE→CMA budget |
--workers N | 0 | Retry workers; zero uses available parallelism |
--seed N | 0 | Root retry seed |
--value-limit N | infinity | Retain only results below this value |
--stop-fitness N | negative infinity | Stop after reaching this objective value |
--progress-interval N | 0 | Live status period in seconds; zero disables |
--max-eval-fac N | 50 | Advanced final budget factor |
--check-interval N | 100 | Advanced diversity checkpoint interval |
Show the installed parser help with:
cargo run --release -p fcmaes-examples --bin gtop-advexamples -- --help
Basic examples
Run all problems with 16 workers:
cargo run --release -p fcmaes-examples --bin gtop-examples -- \
--retries 32 --evaluations 50000 --workers 16 --seed 1
Run only Rosetta:
cargo run --release -p fcmaes-examples --bin gtop-examples -- \
--problem rosetta --retries 32 --evaluations 50000 --workers 16 --seed 1
Messenger Full
Run the long coordinated-retry Messenger Full preset with:
cargo run --release -p fcmaes-examples --bin gtop-advexamples -- \
--problem messenger-full \
--retries 50000 \
--evaluations 1500 \
--workers 16 \
--seed 1 \
--value-limit 12 \
--max-eval-fac 50 \
--check-interval 100 \
--progress-interval 10
This is a large run. max_eval_fac=50 linearly raises the per-retry budget
from 1,500 to 75,000 evaluations across the claimed retry IDs.
Live progress
--progress-interval enables an atomic objective counter and a separate
reporting thread. It writes status to stderr and leaves the final result on
stdout:
progress problem="Messenger full" final=false elapsed=10.0s \
evaluations=... evals_per_second=... retries=.../50000 best=...
The fields are elapsed wall time, objective evaluations observed by the runner, evaluation throughput, completed retry count, and best objective value seen. When all workers are inside their first long retry, evaluations and best value can advance while completed retries remains zero.
Save both progress and the result:
cargo run --release -p fcmaes-examples --bin gtop-advexamples -- \
--problem messenger-full --retries 50000 --evaluations 1500 \
--workers 16 --value-limit 12 --progress-interval 10 \
2>&1 | tee messenger-full.log
The monitor performs one relaxed atomic increment per evaluation and a compare/exchange only when a candidate may improve the global best. It does not place a mutex around objective evaluation.
Output
The final line for each problem contains:
Messenger full: value=... evaluations=... runs=... x=[...]
With a restrictive value limit, value=inf means no completed retry below the
limit was retained. The progress monitor can still show the best objective
observed so far.
Benchmarks
benchmark-gtop runs independent coordinated-retry experiments and emits both
raw samples and a Markdown summary table. Its default problem set excludes
the long-running Tandem and Messenger Full cases:
cargo run --release -p fcmaes-examples --bin benchmark-gtop -- \
--runs 100 --workers 32 --seed 1 \
--raw-output benchmarks/benchmark_gtop_100_raw.tsv
Pass --include-slow to include both slow cases, or --problem NAME to run a
single case, including a slow one. The recorded 100-run measurement and its
methodology are in the benchmark report.
The repository’s recorded Tandem sample was produced resumably with:
python3 benchmarks/run_coordinated_tandem.py
benchmark-biteopt-gtop uses basic retry, includes Tandem, and excludes only
Messenger Full. Its defaults are 100 experiments, 24 workers, 24 retries, and
10,000 evaluations per retry. Run BiteOpt with:
cargo run --release -p fcmaes-examples --bin benchmark-biteopt-gtop -- \
--algo biteopt --runs 100 --workers 24 --retries 24 \
--evaluations 10000 --seed 1 \
--raw-output benchmarks/benchmark_biteopt_gtop_rust_100_raw.tsv
Use --algo de_cma for the two-stage optimizer with a fixed 4,000/6,000
DE/CMA evaluation split:
cargo run --release -p fcmaes-examples --bin benchmark-biteopt-gtop -- \
--algo de_cma --runs 100 --workers 24 --retries 24 \
--evaluations 10000 --seed 1 \
--raw-output benchmarks/benchmark_de_cma_gtop_rust_100_raw.tsv
Both tables report success rate, wall-time statistics, and the mean and population standard deviation of the final optimum across all runs. See the native benchmark index for recorded output and reproduction notes.
The optimizer comparison
uses dependency-isolated adapter crates to compare fcmaes with cmaes,
genetic_algorithms, math-optimisation, and argmin. None of those
alternative crates is added to the public Cargo workspace.
Python-wrapper example
The optional PyO3 extension has a runnable
active CMA-ES example adapted from the
original fcmaes.testfun and fcmaes.test_cma tests. After installing the
extension with Maturin, run it directly or through pytest:
.venv/bin/python examples/python/test_cma.py
.venv/bin/python -m pytest examples/python/test_cma.py