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

mutation GA in progress

parent fd9c5388
No related branches found
No related tags found
No related merge requests found
NAME : portgen-50-1010
COMMENT : portgen N=48, seed=1010
TYPE : TSP
DIMENSION : 48
EDGE_WEIGHT_TYPE : EUC_2D
NODE_COORD_SECTION
1 6734 1453
2 2233 10
3 5530 1424
4 401 841
5 3082 1644
6 7608 4458
7 7573 3716
8 7265 1268
9 6898 1885
10 1112 2049
11 5468 2606
12 5989 2873
13 4706 2674
14 4612 2035
15 6347 2683
16 6107 669
17 7611 5184
18 7462 3590
19 7732 4723
20 5900 3561
21 4483 3369
22 6101 1110
23 5199 2182
24 1633 2809
25 4307 2322
26 675 1006
27 7555 4819
28 7541 3981
29 3177 756
30 7352 4506
31 7545 2801
32 3245 3305
33 6426 3173
34 4608 1198
35 23 2216
36 7248 3779
37 7762 4595
38 7392 2244
39 3484 2829
40 6271 2135
41 4985 140
42 1916 1569
43 7280 4899
44 7509 3239
45 10 2676
46 6807 2993
47 5185 3258
48 3023 1942
......@@ -29,10 +29,16 @@
#include "representation/permutation/problems/tsp/algo/SimpleGreedy.h"
#include "opt/manySolutions/geneticAlgorithm/Population.h"
#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/manySolutions/geneticAlgorithm/GeneticAlgorithm.h"
#include "opt/factory/singleSolution/NeighborFactory.h"
#include "opt/singleSolution/neighborhood/neighbor/IndexNeighbor.h"
using namespace representation::permutation::problems::tsp ;
using namespace opt::manySolutions::geneticAlgorithm ;
......@@ -43,13 +49,18 @@ int main(int argc, char *argv[]) {
typedef TSPEval<SOL> EVAL;
typedef Population<SOL> POPULATION;
typedef selection::TournamentSelection<POPULATION> SELECTION ;
typedef crossover::OXCrossover<POPULATION> CROSSOVER ;
typedef replacement::ElitismReplacement<POPULATION> REPLACEMENT ;
typedef opt::criterion::IterCriterion<POPULATION> STOP ;
typedef mutation::Mutation<POPULATION> MUTATION ;
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");
util::RNGHelper::get()->reseed(120);
std::string ficName = "../../instances/tsp/tsp_test/gC50_01.txt";
std::string ficName = "../../instances/tsp/tsp_test/att48.txt";
std::cout << "Process file :" + ficName << std::endl;
TSP tsp_instance(ficName);
......@@ -69,43 +80,25 @@ int main(int argc, char *argv[]) {
POPULATION population;
population.randomInit(10, tsp_instance.getNumberOfCities(), eval);
population.randomInit(50, tsp_instance.getNumberOfCities(), eval);
population.sort();
std::cout << "the init population (sorted):" << std::endl << population << std::endl ;
STOP stopGen(5) ; // using IterCriterion for the number of generations
STOP stopGen(2000) ; // using TimeCriterion with 2 seconds
SELECTION sel(3, population.size());
CROSSOVER crossover(0.8, eval) ;
// Opérateur de mutation
MUTATION mutation(0.2, eval,*neighbor);
REPLACEMENT replace ;
GA _ga(sel, replace, stopGen) ;
_ga(population) ; // run the genetic algorithm
GA ga(sel, crossover, mutation, replace, stopGen) ;
ga(population) ; // run the genetic algorithm
//sel(population) ; // do a selection
population.sort();
std::cout << "the population after the genetic algorithm:" << std::endl << population << std::endl ;
std::cout << "And the best is: " << population[0].fitness() << std::endl ;
}
/*
* typedef tsp::TSPSol<core::FitnessMin<double>> TSPSOL;
typedef opt::Population<TSPSOL> POPULATION;
// Lien entre les solutions et l'instance, permettant d'évaluer les solutions
typedef tsp::TSPEval<TSPSOL> TSPEVAL;
// Une instance du TSP
tsp::TSP instance("../../instances/tsp/tsp_test/att48.txt");
// évaluateur du TSP
TSPEVAL evaluator(instance);
// Création d'une population
opt::Population<TSPSOL> population(50);
// Initialisation aléatoire de la population
population.randomInit(instance.getNumberOfCities(), evaluator);
// Opérateur de sélection
*/
\ No newline at end of file
......@@ -26,8 +26,9 @@ Authors: Olivier Caron and additional contributors (see Authors)
#include "core/Criterion.h"
#include "opt/manySolutions/geneticAlgorithm/selection/Selection.h"
#include "opt/manySolutions/geneticAlgorithm/crossover/Crossover.h"
#include "opt/manySolutions/geneticAlgorithm/mutation/Mutation.h"
#include "opt/manySolutions/geneticAlgorithm/replacement/Replacement.h"
#include "Mutation.h"
namespace opt::manySolutions::geneticAlgorithm {
......@@ -38,7 +39,7 @@ namespace opt::manySolutions::geneticAlgorithm {
template<typename POPULATION>
class GeneticAlgorithm : public core::Algorithm<POPULATION> {
public:
typedef typename POPULATION::SOLUTION_TYPE INDIVIDUAL;
/**
* Constructor of a Genetic Algorithm
......@@ -48,11 +49,11 @@ namespace opt::manySolutions::geneticAlgorithm {
* @param _criterion stop criterion
*/
explicit GeneticAlgorithm(selection::Selection<POPULATION> &_selection,
//crossover::Crossover<POPULATION> &_crossover,mutation::Mutation<POPULATION> &_mutation ,
crossover::Crossover<POPULATION> &_crossover, mutation::Mutation<POPULATION> &_mutation ,
replacement::Replacement<POPULATION> &_replacement,
core::Criterion<POPULATION> &_criterion)
: selection(&_selection)
//, crossover(&_crossover), mutation(&_mutation)
,crossover(&_crossover), mutation(&_mutation)
,replacement(&_replacement)
{ this->criterion = &_criterion ;
}
......@@ -71,7 +72,7 @@ namespace opt::manySolutions::geneticAlgorithm {
* Initialisation of the algorithm according to an initial population
* @param POPULATION the population
*/
virtual void init(const POPULATION &pop) override {
virtual void init([[maybe_unused]] const POPULATION &pop) override {
this->numberOfGenerations = 0;
this->criterion->init();
}
......@@ -85,12 +86,12 @@ namespace opt::manySolutions::geneticAlgorithm {
while (this->criterion->operator()()) {
this->numberOfGenerations++;
this->selection->operator()(sol);
//this->crossover->operator()(sol);
//this->mutation->operator()(sol);
this->crossover->operator()(this->selection->getSelectedPopulation());
this->mutation->operator()(this->crossover->getOffspring());
this->replacement->operator()(sol,this->mutation->getOffspring()) ;
this->criterion->update();
this->replacement->operator()(sol,this->selection->getSelectedPopulation()) ;
sol.sort();
std::cout << "the population after the generation:"<< this->numberOfGenerations << std::endl << sol << std::endl ;
//sol.sort();
//std::cout << "the population after the generation:"<< this->numberOfGenerations << std::endl << sol << std::endl ;
this->checkpoint->operator()(sol);
}
}
......@@ -119,11 +120,12 @@ namespace opt::manySolutions::geneticAlgorithm {
*/
replacement::Replacement<POPULATION> &getReplacement() { return *replacement; }
protected:
unsigned long long int numberOfGenerations = 0;
selection::Selection<POPULATION> *selection;
crossover::Crossover<POPULATION> *crossover;
//mutation::Mutation<POPULATION> *mutation;
mutation::Mutation<POPULATION> *mutation;
replacement::Replacement<POPULATION> *replacement;
};
......
......@@ -24,6 +24,7 @@ Authors: Olivier Caron and additional contributors (see Authors)
#include "core/Algorithm.h"
#include "util/RNGHelper.h"
#include <utility>
namespace opt::manySolutions::geneticAlgorithm::crossover {
/**
......@@ -35,6 +36,7 @@ namespace opt::manySolutions::geneticAlgorithm::crossover {
class Crossover : public core::Algorithm<POPULATION> {
public:
typedef typename POPULATION::SOLUTION_TYPE INDIVIDUAL;
/**
* constructor
* @param _probability the probability to make a crossover or not
......@@ -46,35 +48,45 @@ class Crossover : public core::Algorithm<POPULATION> {
/**
* abstract method that make a crossover with 2 individuals
* the resulting child must be inserted into the offspring population
* @param _ind1
* @param _ind2
*/
virtual void operator()(INDIVIDUAL &_ind1, INDIVIDUAL &_ind2) = 0;
virtual void operator()(POPULATION &_population) override {
std::vector<INDIVIDUAL> temp ;
temp.clear() ;
unsigned long long int popSize=_population.size() ;
while(temp.size()<popSize){
unsigned long long int i1,i2 ;
i1 = util::RNGHelper::get()->random(popSize);
do{
i2 = util::RNGHelper::get()->random(popSize);
}while(i1==i2);
if(util::RNGHelper::get()->uniform(1) < this->probability){
operator()(_population[i1], _population[i2]);
eval(_population[i1]) ; eval(_population[i2]) ;
virtual std::pair<INDIVIDUAL,INDIVIDUAL> operator()(const INDIVIDUAL &_ind1, const INDIVIDUAL &_ind2) = 0;
void operator()(POPULATION &_population) override {
this->offspring.clear();
unsigned long long int pair_size = _population.size()%2 ==0 ? _population.size() : _population.size()-1 ;
unsigned long long int counter=0 ;
while (counter < pair_size) {
INDIVIDUAL ind1 = _population[counter] ; INDIVIDUAL ind2 = _population[counter+1] ;
if (util::RNGHelper::get()->normal(1) < this->probability) {
std::pair<INDIVIDUAL,INDIVIDUAL> pair_result= this->operator()(ind1, ind2);
this->eval(pair_result.first) ; this->eval(pair_result.second) ;
this->offspring.push_back(pair_result.first);
this->offspring.push_back(pair_result.second);
} else {
this->offspring.push_back(ind1);
this->offspring.push_back(ind2) ;
}
counter+=2 ;
}
if (_population.size()%2 ==1) { // in case of pop size is not pair
this->offspring.push_back(_population[_population.size()-1]); // complete with the last individual
}
}
/**
* provides the generated offspring
* @return the offspring
*/
POPULATION &getOffspring() {
return this->offspring;
}
protected:
std::vector<INDIVIDUAL> offspring;
POPULATION offspring;
double probability;
core::Eval<INDIVIDUAL> &eval;
unsigned long long int offspringSize;
};
}
#endif //MH_BUILDER_GA_CROSSOVER_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_GA_OX_CROSSOVER_H
#define MH_BUILDER_GA_OX_CROSSOVER_H
#include "opt/manySolutions/geneticAlgorithm/crossover/Crossover.h"
#include "core/Eval.h"
#include "util/RNGHelper.h"
namespace opt::manySolutions::geneticAlgorithm::crossover {
/**
* Class representing the Order Crossover (OX) operator
* @tparam POPULATION
*/
template<typename POPULATION>
class OXCrossover : public Crossover<POPULATION> {
public:
typedef typename POPULATION::SOLUTION_TYPE INDIVIDUAL;
/**
* constructor
* @param _probability the probability to make a crossover or not
* @param _eval the evaluation of an individual
*/
explicit OXCrossover(double _probability,
core::Eval<INDIVIDUAL> &_eval)
: Crossover<POPULATION>(_probability, _eval) {}
/**
* run the OX crossover
* @param _ind1
* @param _ind2
* @return the children
*/
std::pair<INDIVIDUAL, INDIVIDUAL> operator()(const INDIVIDUAL &_ind1, const INDIVIDUAL &_ind2) override {
unsigned long long int size = _ind1.size();
unsigned int len = util::RNGHelper::get()->random(size);
unsigned int position = util::RNGHelper::get()->random(size - len);
INDIVIDUAL child1;
INDIVIDUAL child2;
for (unsigned long long int i = 0, i1 = 0, i2 = 0; i < size; i++) {
if (i >= position && i < position + len) {
child1.push_back(_ind1[i]);
child2.push_back(_ind2[i]);
} else {
while (std::find(_ind1.begin() + position, _ind1.begin() + position + len, _ind2[i2])
!= _ind1.begin() + position + len)
i2++;
child1.push_back(_ind2[i2]);
i2++;
while (std::find(_ind2.begin() + position, _ind2.begin() + position + len, _ind1[i1])
!= _ind2.begin() + position + len)
i1++;
child2.push_back(_ind1[i1]);
i1++;
}
}
std::pair<INDIVIDUAL, INDIVIDUAL> result;
result.first = child1;
result.second = child2;
return result ;
}
};
}
#endif //MH_BUILDER_GA_OX_CROSSOVER_H
\ No newline at end of file
......@@ -19,20 +19,59 @@
Authors: Olivier Caron and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_GA_MUTATION_H
#define MH_BUILDER_GA_MUTATION_H
#ifndef MH_BUILDER_GA_ONE_POINT_CROSSOVER_H
#define MH_BUILDER_GA_ONE_POINT_CROSSOVER_H
#include "core/Algorithm.h"
#include "opt/manySolutions/geneticAlgorithm/crossover/Crossover.h"
#include "core/Eval.h"
#include "util/RNGHelper.h"
namespace opt::manySolutions::geneticAlgorithm {
namespace opt::manySolutions::geneticAlgorithm::crossover {
/**
* Class representing an abstract Genetic Operator
* Class representing the One Point Crossover operator
* @tparam POPULATION
*/
template<typename POPULATION>
class Mutation : public core::Algorithm<POPULATION> {
class OnePointCrossover : public Crossover<POPULATION> {
public:
Mutation() {}
typedef typename POPULATION::SOLUTION_TYPE INDIVIDUAL;
/**
* constructor
* @param _probability the probability to make a crossover or not
* @param _eval the evaluation of an individual
*/
explicit OnePointCrossover(double _probability,
core::Eval<INDIVIDUAL> &_eval)
: Crossover<POPULATION>(_probability,_eval) {}
/**
* run the one point crossover ,
* @param _ind1
* @param _ind2
*/
std::pair<INDIVIDUAL, INDIVIDUAL> operator()(const INDIVIDUAL &_ind1, const INDIVIDUAL &_ind2) override{
unsigned long long int size = _ind1.size();
unsigned long long int point = util::RNGHelper::get()->random(size);
INDIVIDUAL child1; child1.clear() ;
INDIVIDUAL child2; child2.clear() ;
for(unsigned long long int i=0; i<size; i++){
if(i<=point){
child1.push_back(_ind1[i]);
child2.push_back(_ind2[i]);
}else{
child1.push_back(_ind2[i]);
child2.push_back(_ind1[i]);
}
}
std::pair<INDIVIDUAL, INDIVIDUAL> result ;
result.first=child1 ; result.second=child2 ;
return result ;
}
};
}
#endif //MH_BUILDER_GA_MUTATION_H
#endif //MH_BUILDER_GA_ONE_POINT_CROSSOVER_H
\ No newline at end of file
/***************************************************************************************
* 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_GA_MUTATION_H
#define MH_BUILDER_GA_MUTATION_H
#include "core/Algorithm.h"
#include "util/RNGHelper.h"
#include "opt/singleSolution/neighborhood/neighbor/IndexNeighbor.h"
using opt::singleSolution::neighborhood::neighbor::IndexNeighbor ;
namespace opt::manySolutions::geneticAlgorithm::mutation {
/**
* Class representing a Mutation operator
* the strategy depends of the chosen neighbor
* @tparam POPULATION
*/
template<typename POPULATION>
class Mutation : public core::Algorithm<POPULATION> {
public:
typedef typename POPULATION::SOLUTION_TYPE INDIVIDUAL;
/**
* constructor
* @param _probability the probability to make a crossover or not
* @param _eval the evaluation of an individual
*/
explicit Mutation(double _probability,
core::Eval<INDIVIDUAL> &_eval, IndexNeighbor<INDIVIDUAL> &_indexNeighbor)
: probability(_probability), eval(_eval), indexNeighbor(&_indexNeighbor) {}
/**
* The running process that realise a mutation for the given population
* @param _population
*/
void operator()(POPULATION &_population) override {
this->offspring.clear();
for (INDIVIDUAL ind : _population) {
if (util::RNGHelper::get()->normal(1) < this->probability) {
INDIVIDUAL mutated = this->operator()(ind);
this->eval(mutated);
this->offspring.push_back(mutated) ;
} else
this->offspring.push_back(ind) ;
}
}
/**
* provides the generated offspring
* @return the offspring
*/
POPULATION &getOffspring() {
return this->offspring;
}
/**
* returns the used neighbor operator
*/
IndexNeighbor<INDIVIDUAL> &getIndexNeighbor() { return *this->indexNeighbor ;}
/**
* Set a new neighbor
* @param neighbor
*/
void setIndexNeighbor(IndexNeighbor<INDIVIDUAL> & neighbor) { this->indexNeighbor = &neighbor ;}
private:
/**
* run the mutation
* @param _ind1
* @return the mutated individual
*/
INDIVIDUAL operator()(const INDIVIDUAL &_ind) {
INDIVIDUAL mutated = _ind ;
this->indexNeighbor->init(mutated);
this->indexNeighbor->setKey(util::RNGHelper::get()->uniform(indexNeighbor->getMaxKey()));
indexNeighbor->operator()(mutated);
return mutated;
}
protected:
POPULATION offspring;
double probability;
core::Eval<INDIVIDUAL> &eval;
opt::singleSolution::neighborhood::neighbor::IndexNeighbor<INDIVIDUAL> *indexNeighbor;
};
}
#endif //MH_BUILDER_GA_MUTATION_H
......@@ -19,8 +19,8 @@
Authors: Lucien Mousin and additional contributors (see Authors)
****************************************************************************************/
#ifndef MH_BUILDER_PERMUTATIONSOLUTION_H
#define MH_BUILDER_PERMUTATIONSOLUTION_H
#ifndef MH_BUILDER_PERMUTATION_SOLUTION_H
#define MH_BUILDER_PERMUTATION_SOLUTION_H
#include "representation/VectorSolution.h"
#include "util/RNGHelper.h"
......@@ -52,7 +52,16 @@ namespace representation::permutation {
this->vec_[i] = i;
}
}
/**
* check that values in the solution are unique from 0 to n
**/
bool isUnique() {
std::sort(this->vec_.begin(), this->vec_.end());
auto current = this->vec_[0] ;
for (unsigned long long int i= 1; i < this->vec_.size(); i++)
if (this->vec_[i] != (1+current++)) return false ;
return true ;
}
/**
* invert the section between i and j in the permutation
* @param i start of inversion [include]
......@@ -121,4 +130,4 @@ namespace representation::permutation {
}
}
#endif //MH_BUILDER_PERMUTATIONSOLUTION_H
#endif //MH_BUILDER_PERMUTATION_SOLUTION_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment