Thanks for your interest in contributing! ex-opt is a C++20 black-box optimization framework, and we welcome contributions of all kinds — bug fixes, new algorithms, documentation, or performance improvements.
- A modern C++20 compiler (GCC >= 11, Clang >= 13)
- CMake >= 3.25
- Git
git clone --recursive https://github.com/SYSUljz/ex-opt.git
cd ex-opt
cmake -B build -S . -DEX_OPT_BUILD_TESTS=ON -DEX_OPT_BUILD_EXAMPLES=ON
cmake --build build -j$(nproc)Run the test suite to make sure everything works:
cd build && ctest --output-on-failure- Fork the repository and create your branch from
main. - Write code following the project's style conventions (see below).
- Add tests for any new functionality. We target high coverage.
- Run the full test suite to ensure nothing is broken.
- Format your code using the provided script:
python3 scripts/format.py
- Submit a pull request with a clear description of your changes.
Use conventional commit prefixes to keep history readable:
[feat]— new feature or algorithm[fix]— bug fix[refactor]— code restructuring without behavior change[docs]— documentation only[test]— test additions or improvements[build]— build system, CI, or dependency changes
Example: [feat] add Differential Evolution policy
- Keep PRs focused. One feature or fix per PR.
- Link any related issues.
- Make sure CI passes before requesting review.
- New algorithms must include convergence tests on standard benchmark functions.
We use clang-format with a Google-style-based configuration (120-column limit, C++20 include regrouping). The project follows modern C++20 idioms:
- Prefer concepts over SFINAE or
std::enable_if - Use
std::spanfor array views,std::rangesalgorithms where applicable - Document public APIs with Doxygen-style comments
- Match the existing naming conventions:
PascalCasefor types,snake_casefor functions - Put algorithm-specific code under
include/policy/andsrc/policy/
ex-opt separates algorithm logic from execution scheduling. When adding an algorithm:
- Decide whether it's batch (population-based) or Stream (sequential).
- Implement a
*Policyclass inheriting fromBatchPolicy<State>orStreamPolicy<State>. - Put settings, solver, and result types in the same header.
- Add an overload in
include/optimize.hfor the convenience API. - Add tests in
test/that verify convergence on at least the Sphere function.
include/
├── ex_opt.h # Core framework: WorkActor, Orchestrator, StreamOrchestrator
├── optimize.h # Convenience optimize() API
├── boundary.h # Search space / boundary definitions
├── logging.h # spdlog wrappers
└── policy/
├── base_policy.h # Abstract BatchPolicy / StreamPolicy
├── mapped_policy.h # Mapper adapters for custom structs
├── particle_swarm_optimization.h
├── genetic_algorithm.h
└── simulated_annealing.h
src/
├── logging.cpp
└── policy/
├── particle_swarm_optimization.cpp
├── genetic_algorithm.cpp
└── simulated_annealing.cpp
test/
├── pso_test.cc
├── ga_test.cc
├── sa_test.cc
├── orchestrator_test.cc
└── struct_test.cc
Feel free to open an issue on GitHub or start a discussion. We're happy to help!