ARRDE (Adaptive Restart-Refine Differential Evolution) is a standalone C++17 library implementing a self-adaptive differential evolution optimizer for bound-constrained, derivative-free minimization.
ARRDE runs a current-to-pbest/1 bin DE variant with external archive, Cauchy/normal parameter adaptation, population-size reduction, and an adaptive restart–refine cycle: it restarts with fresh samples when progress stagnates and switches to a refinement phase that exploits accumulated population and archive records as the evaluation budget nears exhaustion.
ARRDE was originally developed by Khoirul Faiq Muzakka as part of the Minion optimization framework.
This repository is not the original implementation. It is a standalone extraction and simplification of the ARRDE code from Minion, reduced to a single optimizer while preserving its numerical behavior exactly. The extraction history and validation methodology are documented in docs/EXTRACTION.md.
- Single, dependency-free C++17 optimizer (
class ARRDE) - Deterministic, seedable RNG stream per run
- Batch (population) objective interface — evaluate many candidates per call
- Six bound-enforcement strategies
- Latin-hypercube or uniform population initialization
- Optional callback for progress reporting and early stopping
All names live in namespace arrde (header: algorithms/arrde.h).
| Type | Description |
|---|---|
Result | Optimization outcome: x, fun, nit, nfev, status, message |
TerminationStatus | Running, MaxEvaluationsReached, CallbackStopped, RuntimeError |
ObjectiveFunction | std::function<std::vector<double>(const std::vector<std::vector<double>>&, void*)> — receives a batch of candidate points, returns one fitness value per point |
ConfigValue | std::variant<bool, int, double, std::string> option value |
Options | Typed map wrapper; get<T>(key, default) |
classARRDE {
public:ARRDE(ObjectiveFunction func,
const std::vector<std::pair<double,double>>& bounds,
const std::vector<std::vector<double>>& x0 = {},
void* data = nullptr,
std::function<bool(Result*)> callback = nullptr,
size_t maxevals = 100000,
int seed = -1,
std::map<std::string, ConfigValue> options = {});
Result optimize();
};bounds— one{lower, upper}pair per dimension.x0— optional initial guesses (each dimension ofbounds); used to seed the initial population.data— opaque pointer passed through to the objective.callback— invoked with intermediate results; returntrueto stop.seed— seeds the global RNG;-1leaves the RNG unseeded (randomly initialized).- Throws
std::invalid_argumenton invalid bounds or mismatchedx0.
The header also exposes the supporting utilities used by ARRDE:
set_global_seed, get_rng, rand_gen, rand_int, rand_norm,
rand_cauchy, random_choice, argsort, findMin, findArgMin,
findArgMax, clamp, latin_hypercube_sampling, random_sampling,
calcMean, calcStdDev, enforce_bounds.
| Key | Type | Default | Meaning |
|---|---|---|---|
population_size | int | 0 | Initial population size; 0 selects a size automatically from budget and dimensionality |
bound_strategy | string | "reflect-random" | Out-of-bounds handling: clip, reflect, reflect-random, periodic, random, none |
#include"algorithms/arrde.h"
std::vector<double> sphere(const std::vector<std::vector<double>>& X, void*) {
std::vector<double> f;
f.reserve(X.size());
for (constauto& x : X) {
double s = 0.0;
for (double v : x) s += v * v;
f.push_back(s);
}
return f;
}
intmain() {
std::vector<std::pair<double, double>> bounds(10, {-100.0, 100.0});
arrde::ARRDEopt(sphere, bounds, {}, nullptr, nullptr,
100000/*maxevals*/, 42/*seed*/);
arrde::Result res = opt.optimize();
// res.fun - best objective value found// res.x - minimizer// res.nfev - number of objective evaluations used
}A complete runnable example against the CEC-2017 benchmark suite is in
test_arrde_f24.cpp.
Prerequisites: a C++17 compiler and CMake ≥ 3.14. The bundled CEC-2017 benchmark needs its input data:
bash get_cec2017.sh # downloads cec_input_data/
bash build.sh # configures and builds into build/
bash run.sh # runs the F24 regression exampleOr manually:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
./build/test_arrde_f24 # F24, D=30, 300000 evals, seed 42
./build/test_arrde_f24 24 20 300000 20260817 10000algorithms/arrde.h public API: types + ARRDE class + utility templates
algorithms/arrde.cpp optimizer implementation
algorithms/arrde_utils.cpp RNG state, sampling, statistics helpers
algorithms/default_options.h default option values
cec/ CEC-2017 benchmark wrapper (test-only)
test_arrde_f24.cpp example driver / regression entry point
docs/EXTRACTION.md extraction and validation history
docs/extraction/ archived prompts and per-pass analysis reports
build.sh, run.sh convenience scripts
get_cec2017.sh benchmark data downloader
This standalone library was produced through a sequence of small, behavior-preserving refactoring passes, each followed by a deterministic regression test comparing the complete optimizer output byte-for-byte against recorded baselines. Every cleanup stage is therefore verified to leave the algorithm's numerical behavior unchanged.
The refactoring was assisted by AI tools (ChatGPT, OpenCode, Ollama, and local Qwen models); the ARRDE algorithm itself remains the work of its original author.
See LICENSE.