-
-
Notifications
You must be signed in to change notification settings - Fork 3
first_60_minutes
ULTRA is a modern C++ framework for evolutionary computation, including genetic programming, differential evolution, and symbolic regression.
A practical quickstart for newcomers: a successful first run, a tiny custom program, and a clear path for what to learn next.
In one hour you will:
- build ULTRA;
- run a built-in example;
- write and run your own minimal program;
- know where to go next depending on whether you are a user or future contributor.
You need:
- a C++23-capable compiler;
-
cmake; - Python 3 for some helper tools (optional).
ULTRA is primarily supported on Linux and Windows; other platforms may work but can have rough edges.
git clone https://github.com/morinim/ultra.git
cd ultraConfigure:
cmake -B build/ src/Build:
cmake --build build/If this completes without errors, your toolchain is working and you are ready to run examples.
The easiest first run is the differential evolution example based on the Rastrigin function.
Try one of the following (the path may vary depending on generator/platform):
./build/examples/rastriginor, if your generator places binaries at the top-level build directory:
./build/rastriginExpected result: optimisation logs followed by a final line reporting a minimum (near zero for a successful run) and the corresponding coordinates.
...
0.101 380: -1.98952e-13
0.101 381: -1.63425e-13
0.102 384: -1.42109e-13
0.102 385: -1.13687e-13
0.103 386: -5.68434e-14
0.104 391: -1.42109e-14
0.104 393: -7.10543e-15
0.106 398: -0
[INFO] Evolution completed at generation: 1002. Elapsed time: 0.241
Run 0 TRAINING. Fitness: -0
Minimum found: -0
Coordinates: [ -5.21528e-10 2.36987e-09 1.52008e-09 2.08037e-10 3.37312e-09 ]
Create quickstart_rosen.cc in the repository root:
#include "kernel/ultra.h"
// Rosenbrock minimisation converted to maximisation.
double rosenbrock(const ultra::de::individual &x)
{
double s = 0.0;
for (std::size_t i = 0; i + 1 < x.size(); ++i)
{
double a = x[i + 1] - x[i] * x[i];
double b = 1.0 - x[i];
s += 100.0 * a * a + b * b;
}
return -s;
}
int main()
{
ultra::de::problem prob(3, {-3.0, 3.0});
prob.params.population.individuals = 40;
prob.params.evolution.generations = 300;
ultra::de::search search(prob, rosenbrock);
auto result = search.run();
std::cout << "Best fitness: "
<< *result.best_measurements().fitness
<< " at [" << result.best_individual() << "]\n";
}This program runs a simple optimisation using Differential Evolution. It searches for the point that minimises the Rosenbrock function (ULTRA maximises by default, so the function is negated).
Compile and run it using the library you just built:
c++ -std=c++23 -Isrc quickstart_rosen.cc build/kernel/libultra.a -lpthread -o quickstart_rosen
./quickstart_rosenIf your platform or toolchain needs extra libraries, prefer adding this file under src/examples/ and building via CMake instead.

ULTRA usage usually follows this sequence:
-
define a problem (
problem) with domain bounds/data; -
set parameters (
prob.params...) for population and evolution; -
choose a search (
de::search,ga::search,src::search...); -
run (
search.run()); -
inspect results (
best_individual,best_measurements, stats/logs).
If you keep this flow in mind, most examples become easy to read.
-
Build succeeds, executable path not found: check where your generator emits binaries (
build/examples/vsbuild/). - Result quality seems poor: increase generations and/or population first.
- Compiler errors about language features: verify C++23 toolchain.
- Confusion about objective direction: if you are minimizing, return the negative value (as shown above).
- Read and run more examples from
src/examples/. - Try symbolic regression and classification examples.
- Start tuning
prob.paramsand compare solution quality and speed.
- Read
CONTRIBUTING.md. - Learn the structure of
src/kernel,src/utility, andsrc/test. - Run tests and explore sanitizer presets in
src/CMakePresets.json. - Study Software Architecture Document.
cmake --install build/This may require elevated privileges depending on your installation prefix.
- Build completed.
- At least one example executed.
- Custom minimal program compiled and ran.
- You can explain the 5-step mental model.
- You picked a next path (user vs contributor).
If all are checked, you are fully out of "blank page" mode.
