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

nsga-2 in progress

parent bc327627
Branches
No related tags found
No related merge requests found
......@@ -45,7 +45,7 @@ namespace core {
* Get the Fitness
* @return fitness
*/
FIT &fitness() {
virtual FIT &fitness() {
return fitness_;
}
......@@ -53,7 +53,7 @@ namespace core {
* Get the Fitness
* @return fitness
*/
const FIT &fitness() const {
virtual const FIT &fitness() const {
return fitness_;
}
......@@ -61,7 +61,7 @@ namespace core {
* Set the Fitness
* @param f the fitness
*/
void fitness(FIT f) {
virtual void fitness(FIT f) {
fitness_ = f;
}
......@@ -69,7 +69,7 @@ namespace core {
* If the fitness is valid
* @return true if fitness is valid
*/
bool valid() {
virtual bool valid() {
return fitness_.isValid();
}
......@@ -77,7 +77,7 @@ namespace core {
* If the scalarized fitness is valid
* @return true if the scalarised fitness is valid
*/
bool validScalar() {
virtual bool validScalar() {
return fitness_.isValidScalar();
}
......@@ -85,7 +85,7 @@ namespace core {
* Get the flag
* @return the flag
*/
[[nodiscard]] int flag() const {
[[nodiscard]] virtual int flag() const {
return inner_flag;
}
......@@ -93,7 +93,7 @@ namespace core {
* Set the flag
* @param v the flag
*/
void flag(int v) {
virtual void flag(int v) {
inner_flag = v;
}
......@@ -102,7 +102,7 @@ namespace core {
* @param sol solution
* @return true solution have the same fitness
*/
bool operator==(const Solution<FIT> &sol) const {
virtual bool operator==(const Solution<FIT> &sol) const {
return this->fitness_ == sol.fitness();
}
......@@ -111,7 +111,7 @@ namespace core {
* @param sol solution
* @return true solution have note the same fitness
*/
bool operator!=(const Solution<FIT> &sol) const {
virtual bool operator!=(const Solution<FIT> &sol) const {
return this->fitness_ != sol.fitness();
}
......@@ -120,7 +120,7 @@ namespace core {
* @param sol solution
* @return true solution is worse or equal than another solution
*/
bool operator<=(const Solution<FIT> &sol) const {
virtual bool operator<=(const Solution<FIT> &sol) const {
return this->fitness_ <= sol.fitness();
}
......@@ -129,7 +129,7 @@ namespace core {
* @param sol solution
* @return true solution is worse than another solution
*/
bool operator<(const Solution<FIT> &sol) const {
virtual bool operator<(const Solution<FIT> &sol) const {
return this->fitness_ < sol.fitness();
}
......@@ -138,7 +138,7 @@ namespace core {
* @param sol solution
* @return true solution is better or equal than another solution
*/
bool operator>=(const Solution<FIT> &sol) const {
virtual bool operator>=(const Solution<FIT> &sol) const {
return this->fitness_ >= sol.fitness();
}
......@@ -147,10 +147,18 @@ namespace core {
* @param sol solution
* @return true solution is better than another solution
*/
bool operator>(const Solution<FIT> &sol) const {
virtual bool operator>(const Solution<FIT> &sol) const {
return this->fitness_ > sol.fitness();
}
/**
* Print the solution in an output stream
* @param os output stream
*/
virtual void print(std::ostream &os) const {
this->fitness().printOn(os);
os << "NO REPRESENTATION" ;
if (this->flag()) os << " (VISITED)";
}
protected:
/*! the fitness value */
FIT fitness_;
......@@ -167,9 +175,7 @@ namespace core {
*/
template<typename FIT>
std::ostream &operator<<(std::ostream &os, const Solution<FIT> &solution) {
os << solution.fitness() << " NO REPRESENTATION ";
if ( solution.flag() )
os << " (VISITED) ";
solution.print(os);
return os;
}
}
......
......@@ -96,7 +96,7 @@ namespace core::archive {
};
/**
* Update archive itself (in case a solution changes)
* Update archive itself (in case of a solution changes)
* @return true is the archive changes
*/
bool update() override {
......
......@@ -30,7 +30,7 @@ Authors: Olivier Caron and additional contributors (see Authors)
#include "opt/manySolutions/geneticAlgorithm/mutation/Mutation.h"
#include "opt/manySolutions/geneticAlgorithm/replacement/Replacement.h"
#include "opt/manySolutions/geneticAlgorithm/NS_GA2_Population.h"
#include "opt/manySolutions/geneticAlgorithm/NSGA2_Population.h"
#include "opt/manySolutions/geneticAlgorithm/NSGA2_Solution.h"
#include "opt/manySolutions/geneticAlgorithm/selection/TournamentSelection.h"
#include <vector>
......@@ -97,78 +97,7 @@ namespace opt::manySolutions::geneticAlgorithm {
}
}
static std::vector<std::vector<NSGA2_Solution<INDIVIDUAL>>> fastNonDominatedSort(
std::vector<NSGA2_Solution<INDIVIDUAL>>
&P) {
std::vector<std::vector<NSGA2_Solution<INDIVIDUAL>>> F;
F.clear();
for (NSGA2_Solution<INDIVIDUAL> &p: P) {
p.getS().clear(); // S_p = {}
p.setN(0); // n_p = 0
for (NSGA2_Solution<INDIVIDUAL> &q: P) {
if (p.getIndividual().fitness() > q.getIndividual().fitness()) { // if (p dominates q)
p.getS().push_back(&q); // add q to the set of solutions dominated by p
} else if (p.getIndividual().fitness() < q.getIndividual().fitness()) {
p.setN(p.getN() + 1); // increment the domination counter of p
}
}
if (p.getN() == 0) { // p belongs to the first front
p.setRank(0);
if (F.size() == 0) F.push_back({p}); else F[0].push_back(p);
}
}
if (F.size() == 0) return F;
unsigned long long int i = 0;
std::vector<NSGA2_Solution<INDIVIDUAL>> Q;
while (F[i].size() != 0) {
Q.clear();
for (auto &p: F[i]) {
for (auto &q: p.getS()) {
q->setN(q->getN() - 1);
if (q->getN() == 0) {
q->setRank(i + 1);
Q.push_back(*q);
}
}
}
i = i + 1;
F.push_back(Q);
}
F.pop_back();
return F;
}
/**
* set the crowding distance for all individuals stored in Front
* @param Front
*/
static void crowdingDistanceAssignment(std::vector<NSGA2_Solution<INDIVIDUAL>>
&Front) {
auto F_size = Front.size(); // number of solutions in front
if (F_size == 0) return;
for (auto &f: Front) f.setCrowdingDistance(0); // initialize distance
for (unsigned long long int ind_obj = 0;
ind_obj < Front[0].getIndividual().fitness().objectives().size(); ind_obj++) {
// for each objective value m
// sort using each objective value
std::sort(Front.begin(), Front.end(),
[&ind_obj](NSGA2_Solution<INDIVIDUAL> &i1, NSGA2_Solution<INDIVIDUAL> &i2) {
return i1.getIndividual().fitness()[ind_obj] > i2.getIndividual().fitness()[ind_obj];
});
// so that boundary points are always selected
Front[0].setCrowdingDistance(std::numeric_limits<double>::infinity());
Front[F_size - 1].setCrowdingDistance(std::numeric_limits<double>::infinity());
for (unsigned long long int i = 1; i < (F_size - 1); i++) // for all other points
Front[i].setCrowdingDistance(Front[i].getCrowdingDistance() +
(Front[i + 1].getIndividual().fitness()[ind_obj] -
Front[i - 1].getIndividual().fitness()[ind_obj]) /
(Front[0].getIndividual().fitness()[ind_obj] -
Front[F_size - 1].getIndividual().fitness()[ind_obj])
);
}
}
};
}
......
......@@ -25,6 +25,7 @@ Authors: Olivier Caron and additional contributors (see Authors)
#include "core/Eval.h"
#include "core/Archive.h"
#include "opt/manySolutions/geneticAlgorithm/Population.h"
#include "opt/manySolutions/geneticAlgorithm/NSGA2_Solution.h"
#include <vector>
#include <cassert>
......@@ -32,25 +33,87 @@ namespace opt::manySolutions::geneticAlgorithm {
/**
* Class representing a population for Genetic Algorithms
* with additional properties required for NS_GA_2 algorithm
* @tparam SOLUTION
* @ltparam SOL the solution type encapsulated by the NSGA2_Solution decorator
*/
template < typename SOLUTION >
class NS_GA2_Population : public Population<SOLUTION> {
protected:
class NSGA2_Population : public Population<NSGA2_Solution<SOLUTION>> {
public:
/**
* initialize an empty population
*/
NS_GA2_Population() : Population<SOLUTION>() {}
explicit NSGA2_Population() : Population<NSGA2_Solution<SOLUTION>>() {}
static std::vector<std::vector<NSGA2_Solution<SOLUTION>>> fastNonDominatedSort(
std::vector<NSGA2_Solution<SOLUTION>>
&P) {
std::vector<std::vector<NSGA2_Solution<SOLUTION>>> F;
F.clear();
for (NSGA2_Solution<SOLUTION> &p: P) {
p.getS().clear(); // S_p = {}
p.setN(0); // n_p = 0
for (NSGA2_Solution<SOLUTION> &q: P) {
if (p.fitness() > q.fitness()) { // if (p dominates q)
p.getS().push_back(&q); // add q to the set of solutions dominated by p
} else if (p.fitness() < q.fitness()) {
p.setN(p.getN() + 1); // increment the domination counter of p
}
}
if (p.getN() == 0) { // p belongs to the first front
p.setRank(0);
if (F.size() == 0) F.push_back({p}); else F[0].push_back(p);
}
}
if (F.size() == 0) return F;
unsigned long long int i = 0;
std::vector<NSGA2_Solution<SOLUTION>> Q;
while (F[i].size() != 0) {
Q.clear();
for (auto &p: F[i]) {
for (auto &q: p.getS()) {
q->setN(q->getN() - 1);
if (q->getN() == 0) {
q->setRank(i + 1);
Q.push_back(*q);
}
}
}
i = i + 1;
F.push_back(Q);
}
F.pop_back();
return F;
}
/**
* initialize ranks to -1
* set the crowding distance for all SOLUTIONs stored in Front
* @param Front
*/
void initRanks() {
if (this->archive.size()==0) return ;
this->ranks.resize(this->archive.size());
std::fill(this->ranks.begin(), this->ranks.end(), -1);
static void crowdingDistanceAssignment(std::vector<NSGA2_Solution<SOLUTION>>
&Front) {
auto F_size = Front.size(); // number of solutions in front
if (F_size == 0) return;
for (auto &f: Front) f.setCrowdingDistance(0); // initialize distance
for (unsigned long long int ind_obj = 0;
ind_obj < Front[0].fitness().objectives().size(); ind_obj++) {
// for each objective value m
// sort using each objective value
std::sort(Front.begin(), Front.end(),
[&ind_obj](NSGA2_Solution<SOLUTION> &i1, NSGA2_Solution<SOLUTION> &i2) {
return i1.fitness()[ind_obj] > i2.fitness()[ind_obj];
});
// so that boundary points are always selected
Front[0].setCrowdingDistance(std::numeric_limits<double>::infinity());
Front[F_size - 1].setCrowdingDistance(std::numeric_limits<double>::infinity());
for (unsigned long long int i = 1; i < (F_size - 1); i++) // for all other points
Front[i].setCrowdingDistance(Front[i].getCrowdingDistance() +
(Front[i + 1].fitness()[ind_obj] -
Front[i - 1].fitness()[ind_obj]) /
(Front[0].fitness()[ind_obj] -
Front[F_size - 1].fitness()[ind_obj])
);
}
}
};
......
......@@ -31,22 +31,39 @@ Authors: Olivier Caron and additional contributors (see Authors)
* crowding distance for NS_GA2 algorithm
* @tparam SOL the type of the original solution
*/
template<typename SOL>
template<class SOL>
class NSGA2_Solution : public SOL {
public:
using typename SOL::FITNESS;
using typename SOL::TYPE;
typedef SOL::TYPE_ELEMENT TYPE;
typedef SOL::FITNESS FIT ;
typedef typename std::vector<TYPE>::iterator iterator;
typedef typename std::vector<TYPE>::const_iterator const_iterator;
/**
* default constructor
* simple constructor from a given solution
*/
NSGA2_Solution(SOL &_ind) : ind(&_ind), rank(0), crowdingDistance(0.0), n(0) {
NSGA2_Solution(SOL &_ind) : ind(_ind), rank(0), crowdingDistance(0.0), n(0) {
S.clear();
}
/**
* default empty constructor
*/
NSGA2_Solution() = default;
/**
* move assignment operator
* @param sol the NSGA2 solution to copy
* @return
*/
// NSGA2_Solution<SOL>& operator=(NSGA2_Solution<SOL>&& sol) noexcept
// {
// if (this == &sol) return *this ;
// std::cout << "ici ?" << std::endl;
// ind = sol.ind;
// crowdingDistance = sol.crowdingDistance;
// n = sol.n ;
// rank = sol.rank;
// return *this;
// }
/**
* default destructor
*/
......@@ -92,7 +109,7 @@ public:
* provides the inner individual
* @return the individual
*/
SOL getIndividual() { return *this->ind; }
SOL &getIndividual() { return this->ind; }
/**
* provides the domination counter
......@@ -130,7 +147,7 @@ public:
* @return fitness
*/
FIT &fitness() {
return this->ind->fitness();
return this->ind.fitness();
}
/**
......@@ -138,7 +155,7 @@ public:
* @return fitness
*/
const FIT &fitness() const {
return this->ind->fitness();
return this->ind.fitness();
}
/**
......@@ -146,7 +163,7 @@ public:
* @param f the fitness
*/
void fitness(FIT f) {
this->ind->fitness(f);
this->ind.fitness(f);
}
/**
......@@ -154,7 +171,7 @@ public:
* @return true if fitness is valid
*/
bool valid() {
return this->ind->valid();
return this->ind.valid();
}
/**
......@@ -162,7 +179,7 @@ public:
* @return true if the scalarised fitness is valid
*/
bool validScalar() {
return this->ind->validScalar();
return this->ind.validScalar();
}
/**
......@@ -170,7 +187,7 @@ public:
* @return the flag
*/
[[nodiscard]] int flag() const {
return this->ind->flag();
return this->ind.flag();
}
/**
......@@ -179,7 +196,7 @@ public:
* @return true solution have the same fitness
*/
bool operator==(const NSGA2_Solution<SOL> &sol) const {
return this->ind->fitness() == sol.fitness();
return this->ind.fitness() == sol.fitness();
}
/**
......@@ -188,7 +205,7 @@ public:
* @return true solution have note the same fitness
*/
bool operator!=(const NSGA2_Solution<SOL> &sol) const {
return this->ind->fitness() != sol.fitness();
return this->ind.fitness() != sol.fitness();
}
/**
......@@ -197,7 +214,7 @@ public:
* @return true solution is worse or equal than another solution
*/
bool operator<=(const NSGA2_Solution<SOL> &sol) const {
return this->ind->fitness() <= sol.fitness();
return this->ind.fitness() <= sol.fitness();
}
/**
......@@ -206,7 +223,7 @@ public:
* @return true solution is worse than another solution
*/
bool operator<(const NSGA2_Solution<SOL> &sol) const {
return this->ind->fitness() < sol.fitness();
return this->ind.fitness() < sol.fitness();
}
/**
......@@ -215,7 +232,7 @@ public:
* @return true solution is better or equal than another solution
*/
bool operator>=(const NSGA2_Solution<SOL> &sol) const {
return this->ind->fitness() >= sol.fitness();
return this->ind.fitness() >= sol.fitness();
}
/**
......@@ -224,7 +241,7 @@ public:
* @return true solution is better than another solution
*/
bool operator>(const NSGA2_Solution<SOL> &sol) const {
return this->ind->fitness() > sol.fitness();
return this->ind.fitness() > sol.fitness();
}
/**
......@@ -232,13 +249,13 @@ public:
* @param v the flag
*/
void flag(int v) {
this->ind->flag(v);
this->ind.flag(v);
}
/**
* reset the solution
*/
void reset() override { this->ind->reset(); }
void reset() override { this->ind.reset(); }
......@@ -248,7 +265,7 @@ public:
* @return the k^th variable value
*/
TYPE operator[](unsigned int k) {
return this->ind->operator[](k);
return this->ind.operator[](k);
}
/**
......@@ -257,7 +274,7 @@ public:
* @return the k^th variable value
*/
TYPE operator[](unsigned int k) const {
return this->ind->operator[](k);
return this->ind.operator[](k);
}
/**
* update one element of the vector
......@@ -265,7 +282,7 @@ public:
* @param value the new value
*/
void updateElement(int index, TYPE value) {
this->ind->updateElement(index,value);
this->ind.updateElement(index,value);
}
/**
......@@ -273,7 +290,7 @@ public:
* @return the vector size
*/
[[nodiscard]] unsigned long long int size() const {
return this->ind->size();
return this->ind.size();
}
/**
......@@ -281,7 +298,7 @@ public:
* @param i the element to add
*/
virtual void push_back(const TYPE i) {
this->ind->push_back(i);
this->ind.push_back(i);
}
/**
......@@ -290,21 +307,21 @@ public:
* @param element the element to add
*/
virtual void insert(iterator position, const TYPE element) {
this->ind->insert(position, element);
this->ind.insert(position, element);
}
/**
* Remove the last element in the vector and invalidate the fitness
*/
virtual void pop_back() {
this->ind->pop_back();
this->ind.pop_back();
}
/**
* Clear the vector and invalidate the fitness
*/
virtual void clear() {
this->ind->clear();
this->ind.clear();
}
/**
......@@ -312,47 +329,43 @@ public:
* @param v the new vector
*/
virtual void replace(std::vector<TYPE> &v) {
this->ind->replace(v) ;
this->ind.replace(v) ;
}
/**
* Print the vector in an output stream
* @param os output stream
*/
virtual void print(std::ostream &os) const {
this->ind->fitness().printOn(os);
os << ' ' << this->ind->size() << ' ';
for (auto &e: this->ind) {
os << e << " ";
}
void print(std::ostream &os) const override {
this->ind.print(os);
}
/**
* Begin iterator of the vector
*/
const_iterator begin() const {
return this->ind->begin();
return this->ind.begin();
}
/**
* End iterator of the vector
*/
const_iterator end() const {
return this->ind->end();
return this->ind.end();
}
/**
* Begin iterator of the vector
*/
iterator begin() {
return this->ind->begin();
return this->ind.begin();
}
/**
* End iterator of the vector
*/
iterator end() {
return this->ind->end();
return this->ind.end();
}
/**
......@@ -361,7 +374,7 @@ public:
* @return iterator
*/
iterator erase(iterator pos) {
return this->ind->erase(pos);
return this->ind.erase(pos);
}
/**
......@@ -370,7 +383,7 @@ public:
* @return reference of TYPE
*/
virtual TYPE &at(unsigned long long int i) {
return this->ind->at(i);
return this->ind.at(i);
}
/**
* invert the section between i and j in the permutation
......@@ -379,7 +392,7 @@ public:
* @param invalidate invalidate the fitness
*/
void invert(const int i, const int j, const bool invalidate = true) {
this->ind->invert(i,j,invalidate) ;
this->ind.invert(i,j,invalidate) ;
}
/**
......@@ -389,7 +402,7 @@ public:
* @param invalidate invalidate the fitness
*/
void swap(const int i, const int j, const bool invalidate = true) {
this->ind->swap(i,j,invalidate) ;
this->ind.swap(i,j,invalidate) ;
}
/**
......@@ -400,7 +413,7 @@ public:
* @param invalidate invalidate the fitness
*/
void move(const int i, const int j, const bool invalidate = true) {
this->ind->swap(i,j,invalidate) ;
this->ind.swap(i,j,invalidate) ;
}
/*
* Return the hamming distance between two vector solutions.
......@@ -409,25 +422,25 @@ public:
* The complexity time is linear O(n).
**/
double hamming_distance(const NSGA2_Solution<SOL>& sol) const{
return this->ind->hamming_distance(sol) ;
return this->ind.hamming_distance(sol) ;
}
/**
* Return the jaccard distance between two vector solutions.
* */
double jaccard_distance(const NSGA2_Solution<SOL>& sol) const {
return this->ind->jaccard_distance(sol) ;
return this->ind.jaccard_distance(sol) ;
}
/**
* Shuffle the permutation
*/
virtual void shuffle() {
this->ind->shuffle() ;
this->ind.shuffle() ;
}
protected:
SOL *ind;
SOL ind;
unsigned long long int rank; // the calculated rank
double crowdingDistance;
// the following properties are set during the fast-non-dominated-sort procedure
......
......@@ -65,7 +65,7 @@ namespace opt::manySolutions::geneticAlgorithm {
* @return true if the _solution is added to the archive
*/
bool operator()(const SOLUTION &_solution) override {
this->archive.push_back(_solution);
this->push_back(_solution);
return true;
};
......
......@@ -37,7 +37,7 @@ namespace representation {
typedef typename std::vector<TYPE>::iterator iterator;
typedef typename std::vector<TYPE>::const_iterator const_iterator;
typedef TYPE TYPE_ELEMENT ;
/**
* Construct a vector solution of size n
* @param n size of permutation
......@@ -62,7 +62,7 @@ namespace representation {
* @param k k^th variable value
* @return the k^th variable value
*/
TYPE operator[](unsigned int k) {
virtual TYPE operator[](unsigned int k) {
return this->vec_[k];
}
......@@ -71,7 +71,7 @@ namespace representation {
* @param k k^th variable value
* @return the k^th variable value
*/
TYPE operator[](unsigned int k) const {
virtual TYPE operator[](unsigned int k) const {
return this->vec_[k];
}
......@@ -80,7 +80,7 @@ namespace representation {
* @param index the index of the element to changed
* @param value the new value
*/
void updateElement(int index, TYPE value) {
virtual void updateElement(int index, TYPE value) {
this->vec_[index]=value ;
}
......@@ -88,7 +88,7 @@ namespace representation {
* Get size of the vector
* @return the vector size
*/
[[nodiscard]] unsigned long long int size() const {
[[nodiscard]] virtual unsigned long long int size() const {
return this->vec_.size();
}
......@@ -142,38 +142,38 @@ namespace representation {
*/
virtual void print(std::ostream &os) const {
this->fitness_.printOn(os);
os << ' ' << vec_.size() << ' ';
for (auto e: vec_) {
os << e << " ";
os << ' ' << this->size() << ' ';
for (auto e = this->begin();e != this->end(); e++) {
os << *e << " ";
}
}
/**
* Begin iterator of the vector
*/
const_iterator begin() const {
return vec_.begin();
virtual const_iterator begin() const {
return this->vec_.begin();
}
/**
* End iterator of the vector
*/
const_iterator end() const {
return vec_.end();
virtual const_iterator end() const {
return this->vec_.end();
}
/**
* Begin iterator of the vector
*/
iterator begin() {
return vec_.begin();
virtual iterator begin() {
return this->vec_.begin();
}
/**
* End iterator of the vector
*/
iterator end() {
return vec_.end();
virtual iterator end() {
return this->vec_.end();
}
/**
......@@ -181,7 +181,7 @@ namespace representation {
* @param pos
* @return iterator
*/
iterator erase(iterator pos) {
virtual iterator erase(iterator pos) {
return vec_.erase(pos);
}
......@@ -199,7 +199,7 @@ namespace representation {
* @param j end of inversion [include]
* @param invalidate invalidate the fitness
*/
void invert(const int i, const int j, const bool invalidate = true) {
virtual void invert(const int i, const int j, const bool invalidate = true) {
std::reverse(this->vec_.begin() + i, this->vec_.begin() + j + 1);
if (invalidate)
this->fitness_.invalidate();
......@@ -211,7 +211,7 @@ namespace representation {
* @param j the j^th to swap with the i^th
* @param invalidate invalidate the fitness
*/
void swap(const int i, const int j, const bool invalidate = true) {
virtual void swap(const int i, const int j, const bool invalidate = true) {
std::swap(this->vec_[i], this->vec_[j]);
if (invalidate)
this->fitness_.invalidate();
......@@ -224,7 +224,7 @@ namespace representation {
* @param j the position to move the i^th element
* @param invalidate invalidate the fitness
*/
void move(const int i, const int j, const bool invalidate = true) {
virtual void move(const int i, const int j, const bool invalidate = true) {
if (i < j) {
auto tmp = this->vec_[i];
std::move(this->vec_.begin() + i + 1, this->vec_.begin() + j + 1, this->vec_.begin() + i);
......@@ -243,7 +243,7 @@ namespace representation {
* the corresponding symbols are different.
* The complexity time is linear O(n).
**/
double hamming_distance(const VectorSolution<FIT,TYPE>& sol) const{
virtual double hamming_distance(const VectorSolution<FIT,TYPE>& sol) const{
double distance = 0;
for(unsigned i = 0; i < sol.size(); ++i){
if(!(vec_[i] == sol[i])) // Use !(a == b) instead of (a != b) to prevent heavy refractoring.
......@@ -255,7 +255,7 @@ namespace representation {
/**
* Return the jaccard distance between two vector solutions.
* */
double jaccard_distance(const VectorSolution<FIT,TYPE>& sol) const {
virtual double jaccard_distance(const VectorSolution<FIT,TYPE>& sol) const {
double similarity = 0;
for(double i = 0; i < sol.size(); ++i){
......
......@@ -35,6 +35,7 @@ namespace representation::permutation {
template<typename FIT, typename TYPE = unsigned long long int>
class PermutationSolution : public representation::VectorSolution<FIT, TYPE> {
public:
/**
* Construct a permutation solution of size n
* @param n size of permutation
......
......@@ -88,8 +88,9 @@ namespace representation::permutation::problems::tsp {
double totalDistance(const TSPSOL &sol) {
double dist = 0;
for (unsigned long long int i = 0; i < (sol.size() - 1); i++)
for (unsigned long long int i = 0; i < (sol.size() - 1); i++) {
dist += tsp.getDistance(sol[i], sol[i + 1]);
}
dist += tsp.getDistance(sol[sol.size() - 1], sol[0]);
return dist;
}
......
......@@ -10,6 +10,7 @@
#include "representation/permutation/problems/tsp/TSPEval.h"
#include "representation/permutation/problems/tsp/TSPEvalBiObjective.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/replacement/NS_GA2_Replacement.h"
......@@ -23,7 +24,7 @@ typedef TSPSol<FIT> SOL;
typedef TSPEvalBiObjective<SOL> EVAL;
typedef opt::manySolutions::geneticAlgorithm::Population<SOL> POPULATION;
typedef opt::manySolutions::geneticAlgorithm::NSGA2_Population<SOL> POPULATION;
......@@ -68,25 +69,26 @@ int main() {
population(decorator);
}
for (SOL &s: population) {
std::cout << "population avant eval:" << std::endl << population << std::endl;
for (auto &s: population) {
eval(s); s.fitness().validate();
std::cout << s << std::endl;
}
std::cout << "the init population (unsorted):" << std::endl << population << std::endl;
// NSGA2 algorithm : _parent_pop : Pt, offspring : Qt
unsigned long long int N = population.size();
std::vector<NSGA2_Solution<SOL>> R; // build Rt=P union Q
R.clear();
for (auto &ind: population) { std::cout << "pop:" << ind << std::endl; }
for (auto &ind: population) { R.push_back(ind) ; }
std::cout << "ok2" << std::endl;
for (auto &i: R) { std::cout << "R:" << i.getIndividual() << std::endl; }
std::vector<std::vector<NSGA2_Solution<SOL>>> F =
opt::manySolutions::geneticAlgorithm::NSGA2_Algorithm<POPULATION>::fastNonDominatedSort(R);
POPULATION::fastNonDominatedSort(R);
for (auto &f : F) {
opt::manySolutions::geneticAlgorithm::NSGA2_Algorithm<POPULATION>::crowdingDistanceAssignment(f);
POPULATION::crowdingDistanceAssignment(f);
for (auto &s : f) {
std::cout << s.getIndividual() << " rank: " << s.getRank() << " dist: "<< s.getCrowdingDistance() << std::endl;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment