Documentation | |
License |
BRKGA-MP-IPR provides a very easy-to-use framework for the Multi-Parent Biased Random-Key Genetic Algorithm with Implict Path Relink (BRKGA-MP-IPR). Assuming that your have a decoder to your problem, we can setup, run, and extract the value of the best solution in less than 5 commands (obvisiously, you may need few other lines fo code to do a proper test).
This C++ version provides a fast prototyping API using C++14 standards and
libraries. All code was developed as a header-only library, and have no
external dependencies other than those included in the package. So, you just
need to copy/check out the files and point your compiler's header path to
BRKGA-MP-IPR folder (-I
on G++ and CLANG++).
This framework can use multiple threads of modern CPUs, by setting a single parameter (assuming that your decoder is thread-safe). This leverage the parallel decoding nature that BRKGAs offer, compared to other (meta) heuristic frameworks.
The code can be compiled using > GCC 7.2 and > Clang 6.0, and it is very probable that it can be compiled using other modern C++ compilers, such as Intel and Microsoft compilers. To use multiple threads, your compiler must support OpenMP. The current version has been long developed, and it is a very mature code used in production in several companies. However, it lacks of a proper unit and coverage testing. Such tests are in the TODO list.
If C++ is not suitable to you, we may find useful the Julia version of this framework. We are also developing a Python version which is in its earlier stages. At this moment, we have no plans to implement the BRKGA-MP-IPR in other languages such as Java or C#. But if you want to do so, you are must welcome. But please, keep the API as close as possible to the C++ API (or Julia API in case you decide go C), and use the best coding and documentation practices of your chosen language/framework.
If you are not familiar with how BRKGA works, take a look on Standard BRKGA and Multi-Parent BRKGA. In the future, we will provide a Prime on BRKGA-MP section.
BRKGA-MP-IPR is a header-only framework, which means that you only need to download the header files and tell your compiler to include the path to where the files were downloaded.
Quick example (unix): assume we are in an empty folder. So, we copy/clone BRKGA-IPR-MP first:
$ git clone https://github.com/ceandrade/brkga_mp_ipr_cpp
Cloning into 'brkga_mp_ipr_cpp'...
remote: Enumerating objects: 118, done.
remote: Counting objects: 100% (118/118), done.
remote: Compressing objects: 100% (112/112), done.
remote: Total 118 (delta 24), reused 0 (delta 0)
Receiving objects: 100% (118/118), 3.50 MiB | 3.66 MiB/s, done.
Resolving deltas: 100% (24/24), done.
Let's write a test.cpp
with the following code:
#include "brkga_mp_ipr.hpp"
#include <iostream>
int main() {
std::cout << "Testing sense: " << BRKGA::Sense::MINIMIZE;
return 0;
}
Then, let's compile and see it works:
$ g++ --version
g++ (MacPorts gcc8 8.2.0_3) 8.2.0
$ g++ -std=c++14 -Ibrkga_mp_ipr/brkga_mp_ipr test.cpp -o test
$ ./test
Testing sense: MINIMIZE
Note the Git clones the whole repository that contains the library code, documents, and examples. All the examples were built using GNU/Make and GCC toolchain. However, the code is standard C++, and we can quickly adapt it to other toolchains such as Clang, Microsoft, or Intel toolchains. To build this documentation, we also need Doxygen.
The best way to keep it short is to look in the
on examples on the git repo.
Let's take a look into
main_minimal.cpp
,
which solves the
Traveling Salesman Problem (TSP).
This is a trimmed copy:
#include "tsp/tsp_instance.hpp"
#include "decoders/tsp_decoder.hpp"
#include "brkga_mp_ipr.hpp"
#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;
int main(int argc, char* argv[]) {
if(argc < 4) {
cerr << "Usage: "<< argv[0]
<< " <seed> <config-file> <num-generations>"
" <tsp-instance-file>" << endl;
return 1;
}
const unsigned seed = stoi(argv[1]);
const string config_file = argv[2];
const unsigned num_generations = stoi(argv[3]);
const string instance_file = argv[4];
auto instance = TSP_Instance(instance_file);
auto params = BRKGA::readConfiguration(config_file);
auto& brkga_params = params.first;
TSP_Decoder decoder(instance);
BRKGA::BRKGA_MP_IPR<TSP_Decoder> algorithm(
decoder, BRKGA::Sense::MINIMIZE, seed,
instance.num_nodes, brkga_params);
algorithm.initialize();
algorithm.evolve(num_generations);
auto best_cost = algorithm.getBestFitness();
cout << "Best cost: " << best_cost;
return 0;
}
You can identify the following basic steps:
-
Create a data structure to hold your input data. This object should be passed to the decoder object/functor (example
tsp/tsp_instance.hpp
); -
Implement a decoder object/functor. This function translates a chromosome (array of numbers in the interval [0,1]) to a solution for your problem. The decoder must return the solution value or cost to be used as fitness by BRKGA (example
decoders/tsp_decoder.hpp
); -
Load the instance and other relevant data;
-
Read the algorithm parameters using
BRKGA::readConfiguration()
; or create aBRKGA::BrkgaParams
object by hand; -
Create an
BRKGA::BRKGA_MP_IPR
algorithm object; -
Call
BRKGA::BRKGA_MP_IPR::initialize()
to init the BRKGA state; -
Call
BRKGA::BRKGA_MP_IPR::evolve()
to optimize; -
Call
BRKGA::BRKGA_MP_IPR::getBestFitness()
and/orBRKGA::BRKGA_MP_IPR::getBestChromosome()
to retrieve the best solution.
main_minimal.cpp
provides a very minimal example to understand the necessary steps to use the
BRKGA-MP-IPR framework. However,
main_complete.cpp
provides a full-featured code, handy for scientific use, such as
experimentation and paper writing. This code allows fine-grained control of
the optimization, shows several features of BRKGA-MP-IPR such as the resets,
chromosome injection, and others. It also logs
all optimization steps, creating outputs easy to be parsed. You should use
this code for serious business and experimentation.
Check out the tutorial and API documentation: https://ceandrade.github.io/brkga_mp_ipr_cpp
BRKGA-MP-IPR uses a permissive BSD-like license and it can be used as it pleases you. And since this framework is also part of an academic effort, we kindly ask you to remember to cite the originating paper of this work. Indeed, Clause 4 estipulates that "all publications, softwares, or any other materials mentioning features or use of this software (as a whole package or any parts of it) and/or the data used to test it must cite the following article explicitly":
C.E. Andrade. R.F. Toso, J.F. Gonçalves, M.G.C. Resende. The Multi-Parent Biased Random-key Genetic Algorithm with Implicit Path Relinking. European Journal of Operational Research, To appear, 2019. DOI 10.1016/j.ejor.2019.11.037
Check it out the full license.
CI and tests side:
-
Implement unit tests and certify coverage;
-
Configure Travis-Ci correctly, such that we can run tests on Mac OSX and Windows too.