Skip to content
Snippets Groups Projects
Commit 7ecd451d authored by Caron Olivier's avatar Caron Olivier
Browse files

nsga-ii refactoring in progress

parent d7ab2077
Branches
No related tags found
No related merge requests found
......@@ -17,7 +17,7 @@ add_executable(TSP tspMonoObjective.cpp)
add_executable(bTSP tspBiObjective.cpp)
add_executable(TSPTIMEWINDOW tspTimeWindow.cpp)
add_executable(archiveBiObjectiveTSP archiveBiObjectiveTSP.cpp)
add_executable(tspNSGA2BiObjective tspNSGA2BiObjective.cpp)
add_executable(tspGreedy tspGreedy.cpp)
#add_executable(TSPTIMEWINDOW2 tspTimeWindow2.cpp)
......@@ -38,8 +38,10 @@ if(Python_FOUND)
add_executable(tspGA tspGeneticAlgorithm.cpp)
add_executable(ExhaustiveTSP tspExhaustive.cpp)
add_executable(oneMaxGA oneMaxGeneticAlgorithm.cpp)
add_executable(tspNSGA2BiObjective tspNSGA2BiObjective.cpp)
include_directories(${Python_INCLUDE_DIRS})
target_link_libraries(ExhaustiveTSP ${Python_LIBRARIES})
target_link_libraries(tspGA ${Python_LIBRARIES})
target_link_libraries(tspNSGA2BiObjective ${Python_LIBRARIES})
target_link_libraries(oneMaxGA ${Python_LIBRARIES})
endif ()
......@@ -53,16 +53,21 @@ int main() {
typedef opt::criterion::ArchiveEvalCriterion<POPULATION,SOL> STOP ;
typedef GeneticAlgorithm<POPULATION> GA ;
// neighbor operator for mutation step
opt::singleSolution::neighborhood::neighbor::IndexNeighbor<SOL> *neighbor = new representation::bitstring::neighborhood::neighbor::FlipNeighbor<SOL>() ;
std::cout << "********************************************************************************" << std::endl ;
std::cout << "Example of a OneMax optimisation problem mono objective with a genetic algorithm" << std::endl ;
std::cout << "********************************************************************************" << std::endl ;
EVAL eval ;
STOP stopEval(3000,eval) ; // using EvalCriterion with 10000 evaluations
SELECTION sel(40);
CROSSOVER crossover(1, eval) ;
// neighbor operator for mutation step
opt::singleSolution::neighborhood::neighbor::IndexNeighbor<SOL> *neighbor = new representation::bitstring::neighborhood::neighbor::FlipNeighbor<SOL>() ;
MUTATION mutation(1, eval,*neighbor);
REPLACEMENT replace ;
GA ga(sel, crossover, mutation, replace, stopEval) ;
GA ga(&sel, &crossover, &mutation, &replace, &stopEval) ;
for (int run= 1 ; run<=10; run ++) {
util::RNGHelper::get()->reseed(10 * run);
......
......@@ -19,8 +19,6 @@
Authors: Olivier Caron and additional contributors (see Authors)
****************************************************************************************/
#include "util/ParserHelper.h"
#include "util/RNGHelper.h"
#include "core/fitness/FitnessMin.h"
......@@ -32,7 +30,6 @@
#include "opt/manySolutions/geneticAlgorithm/selection/TournamentSelection.h"
#include "opt/manySolutions/geneticAlgorithm/crossover/OXCrossover.h"
#include "opt/manySolutions/geneticAlgorithm/replacement/ElitismReplacement.h"
#include "opt/criterion/IterCriterion.h"
#include "opt/criterion/TimeCriterion.h"
#include "opt/checkpoint/ArchiveCheckpoint.h"
#include "opt/manySolutions/geneticAlgorithm/GeneticAlgorithm.h"
......@@ -59,12 +56,14 @@ int main(void) {
typedef opt::criterion::TimeCriterion<POPULATION> STOP ;
typedef GeneticAlgorithm<POPULATION> GA ;
// neighbor operator for mutation step
opt::factory::singleSolution::NeighborFactory<SOL, opt::singleSolution::neighborhood::neighbor::IndexNeighbor<SOL>> neighborFactory;
opt::singleSolution::neighborhood::neighbor::IndexNeighbor<SOL> *neighbor = neighborFactory.create("2opt");
std::cout << "*****************************************************************************" << std::endl ;
std::cout << "Example of a TSP optimisation problem mono objective with a genetic algorithm" << std::endl ;
std::cout << "*****************************************************************************" << std::endl ;
util::RNGHelper::get()->reseed(120);
std::string ficName = "../../instances/tsp/tsp_test/cgC50_10_01.txt";
std::string ficName = "../../instances/tsp/tsp_test/rat783.tsp";
std::cout << "Process file :" + ficName << std::endl;
TSP tsp_instance(ficName);
......@@ -90,20 +89,22 @@ int main(void) {
solution.shuffle() ; eval(solution);
population(solution);
}
//population.randomInit(50, tsp_instance.getNumberOfCities(), eval);
population.push_back(sol) ; // inserting the solution found by the greedy algorithm
population(sol) ; // inserting the solution found by the greedy algorithm
population.sort();
std::cout << "the init population (sorted):" << std::endl << population << std::endl ;
STOP stopGen(3000) ; // using TimeCriterion with 5 seconds
STOP stopGen(5000) ; // using TimeCriterion with 5 seconds
SELECTION sel(5, population.size()*.8);
CROSSOVER crossover(0.8, eval) ;
// Opérateur de mutation
// neighbor operator for mutation step
opt::factory::singleSolution::NeighborFactory<SOL, opt::singleSolution::neighborhood::neighbor::IndexNeighbor<SOL>> neighborFactory;
opt::singleSolution::neighborhood::neighbor::IndexNeighbor<SOL> *neighbor = neighborFactory.create("2opt");
// mutation operator
MUTATION mutation(0.15, eval,*neighbor);
REPLACEMENT replace ;
......@@ -119,11 +120,14 @@ int main(void) {
std::cout << "And the best solution is: " << population[0].fitness() << std::endl ;
std::cout << "Number of generations : " << ga.getNumberOfGenerations() << std::endl ;
matplotlibcpp::named_plot("GA", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getValues());
matplotlibcpp::named_plot("Obj 1", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getValues(0));
//matplotlibcpp::named_plot("Obj 2", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getValues(1));
matplotlibcpp::xlim(0, 5000);
matplotlibcpp::title("Genetic Algorithm");
matplotlibcpp::xlabel("Time (milliseconds)");
matplotlibcpp::ylabel("fitness 1st objective");
matplotlibcpp::ylabel("fitness objective");
matplotlibcpp::legend();
matplotlibcpp::show();
}
......@@ -21,7 +21,7 @@
#include "util/RNGHelper.h"
#include "../external/mathplotlib/mathplotlib.h"
#include "core/fitness/FitnessMin.h"
#include "representation/permutation/problems/tsp/TSP.h"
......@@ -34,19 +34,15 @@
#include "opt/manySolutions/geneticAlgorithm/crossover/OXCrossover.h"
#include "opt/manySolutions/geneticAlgorithm/mutation/Mutation.h"
#include "opt/manySolutions/geneticAlgorithm/NSGA2_Solution.h"
// #include "opt/manySolutions/geneticAlgorithm/NSGA2_Population.h"
#include "opt/manySolutions/geneticAlgorithm/NSGA2_Algorithm.h"
#include "opt/manySolutions/geneticAlgorithm/NSGA2_Eval.h"
#include "opt/criterion/TimeCriterion.h"
#include "core/archive/AllAcceptedArchive.h"
#include "opt/checkpoint/ArchiveCheckpoint.h"
using namespace representation::permutation::problems::tsp;
#include "core/archive/BoundedArchive.h"
using namespace representation::permutation::problems::tsp;
#include "opt/manySolutions/metrics/BiObjectiveHypervolumeMetric.h"
#include "opt/manySolutions/metrics/BiObjectiveSpreadMetric.h"
......@@ -59,14 +55,15 @@ int main() {
typedef opt::manySolutions::geneticAlgorithm::NSGA2_Solution<SOL> NSGA2_SOL;
// typedef opt::manySolutions::geneticAlgorithm::NSGA2_Population<NSGA2_SOL> POP;
typedef core::archive::AllAcceptedArchive<NSGA2_SOL> POP;
typedef opt::manySolutions::geneticAlgorithm::crossover::OXCrossover<POP> CROSSOVER;
typedef opt::manySolutions::geneticAlgorithm::mutation::Mutation<POP> MUTATION;
typedef opt::criterion::TimeCriterion<POP> STOP;
typedef opt::manySolutions::geneticAlgorithm::NSGA2_Algorithm<POP> GA;
std::cout << "***********************************************************************************" << std::endl ;
std::cout << "Example of a TSP optimisation problem bi objective with a NSGA-II genetic algorithm" << std::endl ;
std::cout << "***********************************************************************************" << std::endl ;
auto seed = 200;
util::RNGHelper::get()->reseed(seed);
......@@ -90,7 +87,6 @@ int main() {
NSGA2_SOL decorator(solution) ; nsga2_eval(decorator);
population(decorator);
}
// population.randomInit(50, tsp_instance1.getNumberOfCities(), nsga2_eval);
std::cout << "Population of the archive initialized: " << std::endl;
std::cout << population << std::endl;
......@@ -103,14 +99,14 @@ int main() {
opt::factory::singleSolution::NeighborFactory<NSGA2_SOL, opt::singleSolution::neighborhood::neighbor::IndexNeighbor<NSGA2_SOL>> neighborFactory;
opt::singleSolution::neighborhood::neighbor::IndexNeighbor<NSGA2_SOL> *neighbor = neighborFactory.create("2opt");
MUTATION mutation(0.15, nsga2_eval, *neighbor);
//opt::checkpoint::ArchiveCheckpoint<POP> archiveCheckpoint;
opt::checkpoint::ArchiveCheckpoint<POP> archiveCheckpoint;
GA ga(
&crossover,
&mutation,
nsga2_eval,
&stopGen);
//ga.setCheckpoint(archiveCheckpoint);
ga.setCheckpoint(archiveCheckpoint);
ga(population); // run the genetic algorithm
......@@ -128,6 +124,14 @@ int main() {
std::cout << "Result: SUCCESS, " << 1;
std::cout << ", [" << hypervolume << ", " << spread << "], " << seed << std::endl;
matplotlibcpp::named_plot("Obj 1", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getValues(0));
matplotlibcpp::named_plot("Obj 2", archiveCheckpoint.getTimeValues(), archiveCheckpoint.getValues(1));
matplotlibcpp::xlim(0, 5000);
matplotlibcpp::title("Genetic Algorithm");
matplotlibcpp::xlabel("Time (milliseconds)");
matplotlibcpp::ylabel("fitness objective");
matplotlibcpp::legend();
matplotlibcpp::show();
return 0;
}
......@@ -198,13 +198,20 @@ namespace core {
return this->archive;
}
/**
* provide the best solution
* provide the best solution for each objective of the solutions
* @return the vector v of solutions such as v[objective_number] = best solution
*/
virtual const SOLUTION & getBestSolution() const {
virtual const std::vector<SOLUTION> getBestSolution() const {
auto numberOfObjectives= this->archive[0].fitness().objectives().size() ;
std::vector<SOLUTION> results ;
for (unsigned long long obj =0 ; obj< numberOfObjectives;obj++) { //for each objective
unsigned long long int indBest = 0;
for (unsigned long long int ind = 1; ind < this->archive.size(); ind++)
if (this->archive[indBest].fitness() < this->archive[ind].fitness()) indBest=ind ;
return this->archive[indBest] ;
if (this->archive[indBest].fitness().objectives()[obj] <
this->archive[ind].fitness().objectives()[obj]) indBest = ind;
results.push_back(this->archive[indBest]);
}
return results ;
}
/**
* Get the selection function that returns the index of a solution
......
......@@ -50,7 +50,7 @@ namespace core {
}
/**
* Get the Fitness
* Get the Fitness (const version)
* @return fitness
*/
virtual const FIT &fitness() const {
......
......@@ -30,7 +30,7 @@ using namespace std ;
namespace opt::checkpoint {
/**
* Class that allows to store checkpoints.
* for one checkpoint, the first objective of a fitness of a solution
* for one checkpoint, the objectives of a fitness of a solution
* and the elapsed time are stored
* @tparam SOL : the type of the solution
*/
......@@ -41,7 +41,7 @@ namespace opt::checkpoint {
typedef typename SOL::FITNESS FIT;
typedef typename FIT::VALUE_TYPE VALUE;
protected:
std::vector<VALUE> values;
std::vector<std::vector<VALUE>> values;
TimeCheckpoint<SOL> time_checkpoint;
public:
......@@ -62,20 +62,20 @@ namespace opt::checkpoint {
void init(const ARCHIVE &_sol);
/**
* add a checkpoint
* @param _sol store the first objective of the fitness of the best sol
* add a checkpoint, store the best solutions for all objectives
* @param _sol
*/
void operator()(const ARCHIVE &_sol);
/**
* provide values (first objective of fitness)
* @tparam SOL
* provide values
* @param unsigned long long int the objective number
* @return vector
*/
virtual std::vector<VALUE> &getValues() ;
virtual std::vector<VALUE> getValues(unsigned long long int objNum) ;
/**
* provide elapsed time values
* provide elapsed time values shared by all objectives
* @return
**/
virtual std::vector<double> &getTimeValues();
......
......@@ -28,8 +28,10 @@
*/
template<typename ARCHIVE>
void ArchiveCheckpoint<ARCHIVE>::init(const ARCHIVE &_arch) {
values.clear();
time_checkpoint.init(_arch.getBestSolution());
auto oneSol = _arch[0];
auto nbObjectives = oneSol.fitness().objectives().size();
values.resize(nbObjectives) ;
time_checkpoint.init(_arch.getBestSolution()[0]);
}
/**
......@@ -38,17 +40,28 @@ void ArchiveCheckpoint<ARCHIVE>::init(const ARCHIVE &_arch) {
*/
template<typename ARCHIVE>
void ArchiveCheckpoint<ARCHIVE>::operator()(const ARCHIVE &_arch) {
values.push_back(_arch.getBestSolution().fitness()[0]);
time_checkpoint(_arch.getBestSolution());
auto bests = _arch.getBestSolution();
auto nbObjectives = this->values.size();
for (unsigned long long int i = 0; i < nbObjectives; i++) {
values[i].push_back(bests[i].fitness().objectives()[i]);
}
time_checkpoint(bests[0]); // a unique time_checkpoint for all objectives
}
/**
* provide values (first objective of fitness of best solutions)
* @tparam ARCHIVE
* provide values
* @param unsigned long long int the objective number
* @return vector
*/
template<typename ARCHIVE>
std::vector<typename ArchiveCheckpoint<ARCHIVE>::VALUE> &ArchiveCheckpoint<ARCHIVE>::getValues() { return values; }
std::vector<typename ArchiveCheckpoint<ARCHIVE>::VALUE> ArchiveCheckpoint<ARCHIVE>::getValues(unsigned long long int objNum) {
// std::vector<typename ArchiveCheckpoint<ARCHIVE>::VALUE> results;
// for (const auto& v : this->values) {
// results.push_back(v[objNum]);
// }
// return results;
return values[objNum];
}
/**
......
......@@ -75,6 +75,7 @@ namespace opt::manySolutions::geneticAlgorithm {
void init([[maybe_unused]] const POPULATION &pop) override {
this->numberOfGenerations = 0;
this->criterion->init();
this->checkpoint->init(pop) ;
}
......
......@@ -209,7 +209,7 @@ namespace opt::manySolutions::geneticAlgorithm {
* Get the Fitness
* @return fitness
*/
FIT &fitness() {
FIT &fitness() override {
return this->ind.fitness();
}
......@@ -217,7 +217,7 @@ namespace opt::manySolutions::geneticAlgorithm {
* Get the Fitness
* @return fitness
*/
const FIT &fitness() const {
const FIT &fitness() const override {
return this->ind.fitness();
}
......@@ -225,7 +225,7 @@ namespace opt::manySolutions::geneticAlgorithm {
* Set the Fitness
* @param f the fitness
*/
void fitness(FIT f) {
void fitness(FIT f) override {
this->ind.fitness(f);
}
......@@ -233,7 +233,7 @@ namespace opt::manySolutions::geneticAlgorithm {
* If the fitness is valid
* @return true if fitness is valid
*/
bool valid() {
bool valid() override {
return this->ind.valid();
}
......@@ -241,7 +241,7 @@ namespace opt::manySolutions::geneticAlgorithm {
* If the scalarized fitness is valid
* @return true if the scalarised fitness is valid
*/
bool validScalar() {
bool validScalar() override {
return this->ind.validScalar();
}
......@@ -249,7 +249,7 @@ namespace opt::manySolutions::geneticAlgorithm {
* Get the flag
* @return the flag
*/
[[nodiscard]] int flag() const {
[[nodiscard]] int flag() const override {
return this->ind.flag();
}
......@@ -491,7 +491,7 @@ namespace opt::manySolutions::geneticAlgorithm {
/**
* Shuffle the permutation
*/
virtual void shuffle() {
virtual void shuffle() override {
this->ind.shuffle();
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment