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

genetic algorithm and onemax debug

parent 5059beec
No related branches found
No related tags found
No related merge requests found
Pipeline #4117 failed
Showing
with 531 additions and 356 deletions
......@@ -30,7 +30,9 @@ find_package(PythonLibs)
if (PYTHONLIBS_FOUND)
add_executable(tspGA tspGeneticAlgorithm.cpp)
add_executable(ExhaustiveTSP tspExhaustive.cpp)
add_executable(oneMaxGA oneMaxGeneticAlgorithm.cpp)
include_directories(${PYTHON_INCLUDE_DIRS})
target_link_libraries(ExhaustiveTSP ${PYTHON_LIBRARIES})
target_link_libraries(tspGA ${PYTHON_LIBRARIES})
target_link_libraries(oneMaxGA ${PYTHON_LIBRARIES})
endif (PYTHONLIBS_FOUND)
/***************************************************************************************
* MH-Builder, a framework for designing adaptive metaheuristics *
* for single and multi-objective optimization. *
* (c) 2019 University of Lille, CNRS *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or (at *
* your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
* for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************
Authors: Olivier Caron and additional contributors (see Authors)
****************************************************************************************/
#include "util/RNGHelper.h"
#include "core/fitness/FitnessMax.h"
#include "representation/bitstring/BitstringSolution.h"
#include "representation/bitstring/problems/onemax/OneMaxEval.h"
#include "opt/manySolutions/geneticAlgorithm/Population.h"
#include "opt/manySolutions/geneticAlgorithm/selection/FitnessProportionateSelection.h"
#include "opt/manySolutions/geneticAlgorithm/crossover/OnePointCrossover.h"
#include "opt/manySolutions/geneticAlgorithm/replacement/ElitismReplacement.h"
#include "opt/criterion/ArchiveEvalCriterion.h"
#include "opt/checkpoint/ArchiveCheckpoint.h"
#include "opt/manySolutions/geneticAlgorithm/GeneticAlgorithm.h"
#include "opt/singleSolution/neighborhood/neighbor/IndexNeighbor.h"
#include "representation/bitstring/neighborhood/neighbor/FlipNeighbor.h"
using namespace opt::manySolutions::geneticAlgorithm ;
int main() {
typedef core::fitness::FitnessMax<unsigned int, unsigned int> FIT;
typedef representation::bitstring::BitstringSolution<FIT> SOL;
typedef representation::bitstring::problems::onemax::OneMaxEval<SOL> EVAL;
typedef Population<SOL> POPULATION;
typedef selection::FitnessProportionateSelection<POPULATION> SELECTION ;
typedef crossover::OnePointCrossover<POPULATION> CROSSOVER ;
typedef replacement::ElitismReplacement<POPULATION> REPLACEMENT ;
typedef mutation::Mutation<POPULATION> MUTATION ;
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>() ;
EVAL eval ;
STOP stopEval(3000,eval) ; // using EvalCriterion with 10000 evaluations
SELECTION sel(40);
CROSSOVER crossover(1, eval) ;
MUTATION mutation(1, eval,*neighbor);
REPLACEMENT replace ;
GA ga(sel, crossover, mutation, replace, stopEval) ;
for (int run= 1 ; run<=10; run ++) {
util::RNGHelper::get()->reseed(10 * run);
POPULATION population;
population.randomInit(40, 512, eval);
ga(population); // run the genetic algorithm
population.sort();
auto cumulativeFitness = population[0].fitness()[0] ;
for (unsigned long long int i=1 ; i< population.size();i++) cumulativeFitness += population[i].fitness()[0];
std::cout << "run" << run << ": Best fitness: " << population[0].fitness()
<< ", Worst fitnesss: " << population[population.size() - 1].fitness()
<< ", Average fitness: " << (cumulativeFitness / population.size()) << std::endl;
}
}
......@@ -80,6 +80,7 @@ int main(int argc, char *argv[]) {
std::cout << "result of simple greedy algorithm " << sol << std::endl;
POPULATION population;
population.randomInit(50, tsp_instance.getNumberOfCities(), eval);
......
......@@ -19,13 +19,15 @@
Authors: Lucien Mousin and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_FITNESSMAX_H
#define MH_BUILDER_FITNESSMAX_H
#ifndef MH_BUILDER_FITNESS_MAX_H
#define MH_BUILDER_FITNESS_MAX_H
#include "core/Fitness.h"
using namespace core;
namespace core {
namespace fitness {
namespace core::fitness {
/**
* Class representing a Maximization Fitness
* @tparam VALUE Type of Fitness (float, int, etc.)
......@@ -34,7 +36,9 @@ namespace core {
template<class VALUE=double, class SCAL_VALUE=double>
class FitnessMax : public Fitness<VALUE, SCAL_VALUE> {
public:
/**
* default constructor
*/
FitnessMax() : Fitness<VALUE, SCAL_VALUE>() {}
/**
......@@ -123,9 +127,9 @@ namespace core {
bool lexicoComp(const FitnessMax &_f) const {
unsigned long long int s = this->objectives_.size();
for (unsigned long long int k = 0; k < s; k++)
if (this->objectives_[k] < _f[k])
if (this->objectives_[k] > _f[k])
return true;
else if (this->objectives_[k] > _f[k])
else if (this->objectives_[k] < _f[k])
return false;
return false;
}
......@@ -147,5 +151,5 @@ namespace core {
};
}
}
#endif //MH_BUILDER_FITNESSMAX_H
#endif //MH_BUILDER_FITNESS_MAX_H
......@@ -19,13 +19,13 @@
Authors: Lucien Mousin and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_FITNESSMIN_H
#define MH_BUILDER_FITNESSMIN_H
#ifndef MH_BUILDER_FITNESS_MIN_H
#define MH_BUILDER_FITNESS_MIN_H
#include "core/Fitness.h"
namespace core {
namespace fitness {
namespace core::fitness {
/**
* Class representing a Minimization Fitness
* @tparam VALUE Type of Fitness (float, int, etc.)
......@@ -34,6 +34,9 @@ namespace core {
template<class VALUE=double, class SCAL_VALUE=VALUE>
class FitnessMin : public Fitness<VALUE, SCAL_VALUE> {
public:
/** default constructor
*
*/
FitnessMin() : Fitness<VALUE, SCAL_VALUE>() {}
/**
......@@ -139,5 +142,5 @@ namespace core {
};
};
}
}
#endif //MH_BUILDER_FITNESSMIN_H
#endif //MH_BUILDER_FITNESS_MIN_H
/***************************************************************************************
* MH-Builder, a framework for designing adaptive metaheuristics *
* for single and multi-objective optimization. *
* (c) 2019 University of Lille, CNRS *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or (at *
* your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
* for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************
Authors: Olivier Caron and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_ARCHIVE_EVAL_CRITERION_H
#define MH_BUILDER_ARCHIVE_EVAL_CRITERION_H
#include "core/Criterion.h"
#include "core/Eval.h"
#include "opt/criterion/EvalCriterion.h"
namespace opt::criterion {
/**
* Class representing a stop criterion for archive based on the number of evaluation
* @tparam IN the archive type
* @tparam SOL the type of an element of the archive
*
*/
template<typename IN, typename SOL>
class ArchiveEvalCriterion : public core::Criterion<IN> {
protected:
EvalCriterion<SOL> evalStop ;
public:
/**
* Constructor of a stop criterion
*/
ArchiveEvalCriterion(unsigned long long int _max_eval, core::Eval<SOL> &_eval) : evalStop(_max_eval,_eval){}
/**
* default destructor
*/
virtual ~ArchiveEvalCriterion() = default ;
/**
* initialisation
*/
void init() override {
this->evalStop.init() ;
}
/**
* update
*/
void update() override {
this->evalStop.update();
}
/**
* tests the stop criterion,
* returns false if number of evaluation is achieved
*/
bool operator()() override {
return this->evalStop.operator()();
}
};
}
#endif //MH_BUILDER_ARCHIVE_EVAL_CRITERION_H
......@@ -19,8 +19,8 @@
Authors: Lucien Mousin and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_EVALCRITERION_H
#define MH_BUILDER_EVALCRITERION_H
#ifndef MH_BUILDER_EVAL_CRITERION_H
#define MH_BUILDER_EVAL_CRITERION_H
#include "core/Criterion.h"
#include "core/Eval.h"
......@@ -78,4 +78,4 @@ namespace opt::criterion {
#include "EvalCriterion.tpp"
}
#endif //MH_BUILDER_EVALCRITERION_H
#endif //MH_BUILDER_EVAL_CRITERION_H
......@@ -30,7 +30,7 @@
template<typename IN>
EvalCriterion<IN>::EvalCriterion(unsigned long long int _max_eval, core::Eval<IN> &_eval) : max_eval(_max_eval),
eval(_eval) {
init_eval = eval.getEvalCounter();
init_eval = this->eval.getEvalCounter();
}
/**
......@@ -38,7 +38,7 @@ EvalCriterion<IN>::EvalCriterion(unsigned long long int _max_eval, core::Eval<IN
*/
template<typename IN>
void EvalCriterion<IN>::init() {
init_eval = eval.getEvalCounter();
this->init_eval = this->eval.getEvalCounter();
}
/**
......@@ -46,7 +46,7 @@ void EvalCriterion<IN>::init() {
*/
template<typename IN>
void EvalCriterion<IN>::update() {
last_check = (eval.getEvalCounter() - init_eval);
this->last_check = (this->eval.getEvalCounter() - this->init_eval);
}
/**
......@@ -56,7 +56,7 @@ void EvalCriterion<IN>::update() {
template<typename IN>
bool EvalCriterion<IN>::operator()() {
this->update();
return last_check < max_eval;
return this->last_check < this->max_eval;
}
/**
......@@ -65,7 +65,7 @@ bool EvalCriterion<IN>::operator()() {
*/
template<typename IN>
void EvalCriterion<IN>::setMaxEval(unsigned long long int _max) {
max_eval = _max;
this->max_eval = _max;
}
/**
......@@ -74,5 +74,5 @@ void EvalCriterion<IN>::setMaxEval(unsigned long long int _max) {
*/
template<typename IN>
unsigned long long int EvalCriterion<IN>::get_max_eval() {
return max_eval;
return this->max_eval;
}
......@@ -19,8 +19,8 @@
Authors: Olivier Caron and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_KEYBOARDHITCRITERION_H
#define MH_BUILDER_KEYBOARDHITCRITERION_H
#ifndef MH_BUILDER_KEYBOARD_HIT_CRITERION_H
#define MH_BUILDER_KEYBOARD_HIT_CRITERION_H
#include "core/Criterion.h"
......@@ -88,4 +88,4 @@ namespace opt::criterion {
}
#endif //MH_BUILDER_KEYBOARDHITCRITERION_H
#endif //MH_BUILDER_KEYBOARD_HIT_CRITERION_H
......@@ -19,8 +19,8 @@
Authors: Lucien Mousin and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_NEIGHBORFACTORY_H
#define MH_BUILDER_NEIGHBORFACTORY_H
#ifndef MH_BUILDER_NEIGHBOR_FACTORY_H
#define MH_BUILDER_NEIGHBOR_FACTORY_H
#include <string>
#include "opt/factory/Factory.h"
......@@ -32,10 +32,10 @@
#include "representation/permutation/neighborhood/neighbor/IncrDoubleBridgeNeighbor.h"
#include "representation/permutation/neighborhood/neighbor/ShiftWithoutSwapNeighbor.h"
#include "representation/permutation/neighborhood/neighbor/SwapNeighbor.h"
#include "representation/bitstring/neighborhood/neighbor/FlipNeighbor.h"
namespace opt {
namespace factory {
namespace singleSolution {
namespace opt::factory::singleSolution {
template<typename SOL, typename NEIGHBOR = opt::singleSolution::neighborhood::neighbor::Neighbor<SOL>>
class NeighborFactory : public opt::factory::Factory<NEIGHBOR, std::string> {
......@@ -59,6 +59,6 @@ namespace opt {
}
};
}
}
}
#endif //MH_BUILDER_NEIGHBORFACTORY_H
#endif //MH_BUILDER_NEIGHBOR_FACTORY_H
......@@ -49,10 +49,10 @@ namespace opt::manySolutions::geneticAlgorithm {
*/
void randomInit(unsigned long long int nb_individuals,
unsigned long long int _solSize, core::Eval<SOLUTION> &_eval){
SOLUTION solution(_solSize);
this->clear() ;
for(unsigned long long int i=0; i<nb_individuals;++i){
solution.shuffle();
SOLUTION solution(_solSize);
_eval(solution);
this->operator()(solution);
}
......
......@@ -39,7 +39,7 @@ namespace opt::manySolutions::geneticAlgorithm::selection {
public:
typedef typename POPULATION::SOLUTION_TYPE INDIVIDUAL;
typedef POPULATION::SOLUTION_TYPE::FITNESS FITNESS;
typedef FITNESS::VALUE_TYPE VALUE;
typedef FITNESS::VALUE_TYPE VALUE_TYPE;
/**
* Constructor of a fitness proportionate selection
......@@ -54,7 +54,7 @@ namespace opt::manySolutions::geneticAlgorithm::selection {
*/
void operator()(const POPULATION &_pop) override {
this->selected.clear();
VALUE totalFitness = _pop[0].fitness()[0] ; // only works with mono objective
VALUE_TYPE totalFitness = _pop[0].fitness()[0] ; // only works with mono objective
for (unsigned long long int i = 1; i < _pop.size();i++) {
totalFitness += _pop[i].fitness()[0];
}
......@@ -68,14 +68,14 @@ namespace opt::manySolutions::geneticAlgorithm::selection {
// Sort the random numbers
sort(randomNums.begin(), randomNums.end());
VALUE cumulativeFitness ;
VALUE_TYPE cumulativeFitness ;
bool deb= true ;
unsigned long long int currentIndex = 0;
// Perform Roulette Wheel Selection
for (const INDIVIDUAL& individual : _pop) {
if (deb)
cumulativeFitness += individual.fitness()[0];
cumulativeFitness = individual.fitness()[0];
else {
deb = false ;
cumulativeFitness += individual.fitness()[0];
......
......@@ -58,7 +58,7 @@ namespace opt::manySolutions::geneticAlgorithm::selection {
INDIVIDUAL winner;
for(unsigned int i = 0; i< this->selectSize; i++){
for(unsigned int j = 0; j < k; j++){
randIndividual = _pop[util::RNGHelper::get()->uniform(_pop.size())];
randIndividual = _pop[util::RNGHelper::get()->random(_pop.size())];
if(j==0){
winner = randIndividual;
}else{
......
......@@ -19,8 +19,8 @@
Authors: Lucien Mousin and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_INDEXNEIGHBORHOOD_H
#define MH_BUILDER_INDEXNEIGHBORHOOD_H
#ifndef MH_BUILDER_INDEX_NEIGHBORHOOD_H
#define MH_BUILDER_INDEX_NEIGHBORHOOD_H
#include "opt/singleSolution/neighborhood/Neighborhood.h"
#include "opt/singleSolution/neighborhood/neighbor/IndexNeighbor.h"
......@@ -117,4 +117,4 @@ namespace opt::singleSolution::neighborhood {
};
}
#endif //MH_BUILDER_INDEXNEIGHBORHOOD_H
#endif //MH_BUILDER_INDEX_NEIGHBORHOOD_H
......@@ -19,8 +19,8 @@
Authors: Lucien Mousin and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_VECTORSOLUTION_H
#define MH_BUILDER_VECTORSOLUTION_H
#ifndef MH_BUILDER_VECTOR_SOLUTION_H
#define MH_BUILDER_VECTOR_SOLUTION_H
#include "core/Solution.h"
......@@ -207,11 +207,17 @@ namespace representation {
}
return 1 - (similarity / sol.size() - similarity);
}
/**
* Shuffle the permutation
*/
void shuffle() {
util::RNGHelper::get()->shuffle(this->vec_.begin(), this->vec_.end());
this->fitness_.invalidate();
}
protected:
/*! Vector of the Permutation */
std::vector<TYPE> vec_;
};
}
#endif //MH_BUILDER_VECTORSOLUTION_H
#endif //MH_BUILDER_VECTOR_SOLUTION_H
......@@ -19,13 +19,13 @@
Authors: Lucien Mousin and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_BITSTRINGSOLUTION_H
#define MH_BUILDER_BITSTRINGSOLUTION_H
#ifndef MH_BUILDER_BITSTRING_SOLUTION_H
#define MH_BUILDER_BITSTRING_SOLUTION_H
#include "representation/VectorSolution.h"
namespace representation {
namespace bitstring {
namespace representation::bitstring {
/**
* Class representing bitstring based solutions
* @tparam FIT Fitness Type
......@@ -33,6 +33,7 @@ namespace representation {
template<typename FIT>
class BitstringSolution : public representation::VectorSolution<FIT, unsigned int> {
public:
typedef unsigned int TYPE ;
/**
* Construct a bitstring solution of size n (all variables at 0)
* @param n size of bitstring
......@@ -40,7 +41,7 @@ namespace representation {
explicit BitstringSolution(unsigned long long int n = 0)
: representation::VectorSolution<FIT, unsigned int>(n) {
for (unsigned long long int i = 0; i < n; i++)
this->vec_.push_back(0);
this->vec_.push_back(util::RNGHelper::get()->random(2)); // either 0 or 1
}
/**
......@@ -75,5 +76,5 @@ namespace representation {
return os;
}
}
}
#endif //MH_BUILDER_BITSTRINGSOLUTION_H
#endif //MH_BUILDER_BITSTRING_SOLUTION_H
......@@ -19,8 +19,8 @@
Authors: Lucien Mousin and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_FLIPNEIGHBOR_H
#define MH_BUILDER_FLIPNEIGHBOR_H
#ifndef MH_BUILDER_FLIP_NEIGHBOR_H
#define MH_BUILDER_FLIP_NEIGHBOR_H
#include "opt/singleSolution/neighborhood/neighbor/IndexNeighbor.h"
......
......@@ -64,6 +64,7 @@ namespace representation {
if (cons[0] > ksp.getWmax())
fit.invalidate();
this->eval_counter++;
}
/**
......@@ -78,6 +79,7 @@ namespace representation {
} else {
operator()(sol);
}
this->eval_counter++;
}
/**
......@@ -99,7 +101,7 @@ namespace representation {
if (cons[0] > ksp.getWmax()) {
fit.invalidate();
}
this->eval_counter++;
}
/**
......
......@@ -19,8 +19,8 @@
Authors: Lucien Mousin and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_ONEMAXEVAL_H
#define MH_BUILDER_ONEMAXEVAL_H
#ifndef MH_BUILDER_ONE_MAX_EVAL_H
#define MH_BUILDER_ONE_MAX_EVAL_H
#include "representation/bitstring/BitstringSolution.h"
#include "core/fitness/FitnessMax.h"
......@@ -29,25 +29,25 @@
namespace representation::bitstring::problems::onemax {
/*! Define type for a OneMax solution */
typedef representation::bitstring::BitstringSolution<core::fitness::FitnessMax<unsigned int>> OneMaxSol;
/**
* Class representing an evaluator for OneMax problem
* @tparam SOL solution type
*/
class OneMaxEval : public core::Eval<OneMaxSol> {
template<typename SOL>
class OneMaxEval : public core::Eval<SOL> {
public:
/**
* Evaluate a OneMax solution
* @param sol a solution
*/
void operator()(OneMaxSol &sol) override {
void operator()(SOL &sol) override {
auto &fit = sol.fitness();
auto objv = fit.objectives();
objv.resize(0);
objv.push_back(count(sol));
fit.objectives(objv);
this->eval_counter++;
}
/**
......@@ -57,7 +57,7 @@ namespace representation::bitstring::problems::onemax {
* @param index the bit to change
* @return the new fitness
*/
static int flip(OneMaxSol &sol, unsigned int fitness, int index) {
static int flip(SOL &sol, unsigned int fitness, int index) {
if (sol[index])
return fitness + 1;
else
......@@ -69,7 +69,7 @@ namespace representation::bitstring::problems::onemax {
* @param sol solution
* @return the number of one in the solution
*/
static int count(OneMaxSol &sol) {
static int count(SOL &sol) {
int p = 0;
for (unsigned long long int j = 0; j < sol.size(); ++j) {
if (sol[j])
......@@ -81,4 +81,4 @@ namespace representation::bitstring::problems::onemax {
}
#endif //MH_BUILDER_ONEMAXEVAL_H
#endif //MH_BUILDER_ONE_MAX_EVAL_H
......@@ -107,13 +107,7 @@ namespace representation::permutation {
this->fitness_.invalidate();
}
/**
* Shuffle the permutation
*/
void shuffle() {
util::RNGHelper::get()->shuffle(this->vec_.begin(), this->vec_.end());
this->fitness_.invalidate();
}
};
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment