Fuzzy Extension of some classical concepts

This commit is contained in:
bahri 2017-05-03 13:34:39 +02:00
commit bc686f7023
11 changed files with 1143 additions and 100 deletions

View file

@ -0,0 +1,137 @@
/*
<moeoExtendedESPEA2.h>
Oumayma BAHRI
Author:
Oumayma BAHRI <oumaymabahri.com>
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOEXTENDEDNSGAII_H_
#define MOEOEXTENDEDNSGAII_H_
#include <eoBreed.h>
#include <eoCloneOps.h>
#include <eoContinue.h>
#include <eoEvalFunc.h>
#include <eoGenContinue.h>
#include <eoGeneralBreeder.h>
#include <eoGenOp.h>
#include <algo/moeoEA.h>
#include <replacement/moeoElitistReplacement.h>
#include <selection/moeoDetTournamentSelect.h>
#include <fitness/moeoDominanceDepthFitnessAssignment.h>
#include <diversity/moeoFuzzyCrowdingDiversity.h>
/**
* Extended NSGAII is an extension of classical algorithm NSGAII for incorporating the aspect of fuzziness in diversity assignement
*/
template < class MOEOT >
class moeoExtendedNSGAII: public moeoEA < MOEOT >
{
public:
/**
* Ctor with a eoContinue, a eoPopEval and a eoGenOp.
* @param _continuator stopping criteria
* @param _popEval population evaluation function
* @param _op variation operators
*/
moeoExtendedNSGAII (eoContinue < MOEOT > & _continuator, eoPopEvalFunc < MOEOT > & _popEval, eoGenOp < MOEOT > & _op) :
defaultGenContinuator(0), continuator(_continuator), eval(defaultEval), defaultPopEval(eval), popEval(_popEval), select(2),
selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(defaultQuadOp, 1.0, defaultMonOp, 1.0),
enBreed(select, _op), breed(genBreed), replace (fitnessAssignment, diversityAssignment)
{}
/**
* Apply a the algorithm to the population _pop until the stopping criteria is satified.
* @param _pop the population
*/
virtual void operator () (eoPop < MOEOT > &_pop)
{
eoPop < MOEOT > offspring, empty_pop;
popEval (empty_pop, _pop); // a first eval of _pop
// evaluate fitness and diversity
fitnessAssignment(_pop);
diversityAssignment(_pop);
do
{
// generate offspring, worths are recalculated if necessary
breed (_pop, offspring);
// eval of offspring
popEval (_pop, offspring);
// after replace, the new pop is in _pop. Worths are recalculated if necessary
replace (_pop, offspring);
}
while (continuator (_pop));
}
protected:
/** a continuator based on the number of generations (used as default) */
eoGenContinue < MOEOT > defaultGenContinuator;
/** stopping criteria */
eoContinue < MOEOT > & continuator;
/** default eval */
class DummyEval : public eoEvalFunc < MOEOT >
{
public:
void operator()(MOEOT &) {}
}
defaultEval;
/** evaluation function */
eoEvalFunc < MOEOT > & eval;
/** default popEval */
eoPopLoopEval < MOEOT > defaultPopEval;
/** evaluation function used to evaluate the whole population */
eoPopEvalFunc < MOEOT > & popEval;
/** default select */
class DummySelect : public eoSelect < MOEOT >
{
public :
void operator()(const eoPop<MOEOT>&, eoPop<MOEOT>&) {}
}
defaultSelect;
/** binary tournament selection */
moeoDetTournamentSelect < MOEOT > select;
/** default select many */
eoSelectMany < MOEOT > selectMany;
/** select transform */
eoSelectTransform < MOEOT > selectTransform;
/** a default crossover */
eoQuadCloneOp < MOEOT > defaultQuadOp;
/** a default mutation */
eoMonCloneOp < MOEOT > defaultMonOp;
/** an object for genetic operators (used as default) */
eoSGAGenOp < MOEOT > defaultSGAGenOp;
/** default transform */
class DummyTransform : public eoTransform < MOEOT >
{
public :
void operator()(eoPop<MOEOT>&) {}
}
defaultTransform;
/** general breeder */
eoGeneralBreeder < MOEOT > genBreed;
/** breeder */
eoBreed < MOEOT > & breed;
/** fitness assignment*/
FitnessAssignment < MOEOT > fitnessAssignment;
/** diversity assignment */
moeoFuzzyCrowdingDiversity < MOEOT > diversityAssignment;
/** elitist replacement */
ElitistReplacement < MOEOT > replace;
};
#endif /*MOEOEXTENDEDNSGAII_H_*/

View file

@ -0,0 +1,156 @@
/*
<moeoExtendedSPEA2.h>
Oumayma BAHRI
Author:
Oumayma BAHRI <oumaymabahri.com>
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOEXTENDEDSPEA2_H_
#define MOEOEXTENDEDSPEA2_H_
#include <eoBreed.h>
#include <eoCloneOps.h>
#include <eoContinue.h>
#include <eoEvalFunc.h>
#include <eoGenContinue.h>
#include <eoGeneralBreeder.h>
#include <eoGenOp.h>
#include <eoPopEvalFunc.h>
#include <eoSGAGenOp.h>
#include <algo/moeoEA.h>
#include <GenerationalReplacement.h>
#include <DetTournamentSelect.h>
#include <selection/moeoSelectFromPopAndArch.h>
#include <diversity/moeoFuzzyNearestNeighborDiversity.h>
#include <distance/moeoBertDistance.h>
#include <archive/moeoFuzzyFixedSizeArchive.h">
/**
* Extended SPEA2 is an extension of classical algorithm SPEA2 for incorporating the aspect of fuzziness in diversity assignment
*/
template < class MOEOT >
class moeoExtendedSPEA2: public moeoEA < MOEOT >
{
public:
/**
* Ctor with a crossover, a mutation and their corresponding rates.
* @param _maxGen number of generations before stopping
* @param _eval evaluation function
* @param _crossover crossover
* @param _pCross crossover probability
* @param _mutation mutation
* @param _pMut mutation probability
* @param _archive archive
* @param _k the k-ieme distance used to fixe diversity
* @param _nocopy boolean allow to consider copies and doublons as bad elements whose were dominated by all other MOEOT in fitness assignment.
*/
moeoExtendedSPEA2 (unsigned int _maxGen, eoEvalFunc < MOEOT > & _eval, eoQuadOp < MOEOT > & _crossover,
double _pCross, eoMonOp < MOEOT > & _mutation, double _pMut, moeoFuzzyArchive < MOEOT >& _archive,
unsigned int _k=1, bool _nocopy=false) :
defaultGenContinuator(_maxGen), continuator(defaultGenContinuator), eval(_eval), loopEval(_eval),
popEval(loopEval), archive(_archive),defaultSelect(2),select(defaultSelect, defaultSelect, _archive, 0.0),
defaultSGAGenOp(_crossover, _pCross, _mutation, _pMut), fitnessAssignment(_archive, _nocopy),
genBreed(defaultSelect, defaultSGAGenOp),selectMany(defaultSelect,0.0), selectTransform(selectMany, dummyTransform),
breed(genBreed), FuzzydiversityAssignment(dist,_archive, _k)
{}
/**
* Apply a few generation of evolution to the population _pop until the stopping criteria is verified.
* @param _pop the population
*/
virtual void operator () (eoPop < MOEOT > &_pop)
{
eoPop < MOEOT >empty_pop, offspring;
popEval (empty_pop, _pop);// a first eval of _pop
fitnessAssignment(_pop); //a first fitness assignment of _pop
diversityAssignment(_pop);//a first diversity assignment of _pop
archive(_pop);//a first filling of archive
while (continuator (_pop))
{
// generate offspring, worths are recalculated if necessary
breed (_pop, offspring);
popEval (_pop, offspring); // eval of offspring
// after replace, the new pop is in _pop. Worths are recalculated if necessary
replace (_pop, offspring);
fitnessAssignment(_pop); //fitness assignment of _pop
diversityAssignment(_pop); //diversity assignment of _pop
archive(_pop); //control of archive
}
}
protected:
/** dummy evaluation */
class eoDummyEval : public eoEvalFunc< MOEOT >
{
public:
void operator()(MOEOT &) {}
}
dummyEval;
/** dummy transform */
class eoDummyTransform : public eoTransform<MOEOT>
{
public :
void operator()(eoPop<MOEOT>&) {}
}
dummyTransform;
/** a continuator based on the number of generations (used as default) */
eoGenContinue < MOEOT > defaultGenContinuator;
/** stopping criteria */
eoContinue < MOEOT > & continuator;
/** evaluation function */
eoEvalFunc < MOEOT > & eval;
/** loop eval */
eoPopLoopEval < MOEOT > loopEval;
/** evaluation function used to evaluate the whole population */
eoPopEvalFunc < MOEOT > & popEval;
/**SelectOne*/
moeoDetTournamentSelect < MOEOT > defaultSelect;
/** binary tournament selection */
SelectFromPopAndArch < MOEOT > select;
/** a default mutation */
eoMonCloneOp < MOEOT > defaultMonOp;
/** a default crossover */
eoQuadCloneOp < MOEOT > defaultQuadOp;
/** an object for genetic operators (used as default) */
eoSGAGenOp < MOEOT > defaultSGAGenOp;
/** general breeder */
eoGeneralBreeder < MOEOT > genBreed;
/** selectMany */
eoSelectMany <MOEOT> selectMany;
/** select Transform*/
eoSelectTransform <MOEOT> selectTransform;
/** breeder */
eoBreed < MOEOT > & breed;
/** Fuzzy archive*/
moeoFuzzyArchive < MOEOT >& archive;
/** diversity assignment used in E-SPEA2 */
moeoFuzzyNearestNeighborDiversity < MOEOT > diversityAssignment;
/** elitist replacement */
moeoGenerationalReplacement < MOEOT > replace;
/**Bert distance*/
moeoBertDistance < MOEOT > dist;
};
#endif /*MOEOEXTENDEDSPEA2_H_*/

View file

@ -0,0 +1,194 @@
/*
<moeoFuzzyArchive.h>
Oumayma BAHRI
Author:
Oumayma BAHRI <oumaymabahri.com>
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOFUZZYARCHIVE_H_
#define MOEOFUZZYARCHIVE_H_
#include <eoPop.h>
#include <comparator/moeoFuzzyParetoComparator.h>
/**
* Abstract class for representing an archive in a fuzzy space of solutions;
* an archive is a secondary population that stores non-dominated fuzzy solutions.
*/
template < class MOEOT >
class moeoFuzzyArchive : public eoPop < MOEOT >, public eoUF < const MOEOT &, bool>, public eoUF < const eoPop < MOEOT > &, bool>
{
public:
using eoPop < MOEOT > :: size;
using eoPop < MOEOT > :: operator[];
using eoPop < MOEOT > :: back;
using eoPop < MOEOT > :: pop_back;
/**
* The type of an objective vector for a solution
*/
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* ctor.
* The FuzzyComparator is used to compare fuzzy solutions based on Pareto dominance
* @param _replace boolean which determine if a solution with the same objectiveVector than another one, can replace it or not
*/
moeoFuzzyArchive(FuzzyComparator< ObjectiveVector > & _comparator, bool _replace=true) : eoPop < MOEOT >(), comparator(_comparator), replace(_replace)
{}
/**
* Returns true if the current archive dominates _objectiveVector according to the moeoObjectiveVectorComparator given in the constructor
* @param _objectiveVector the objective vector to compare with the current archive
*/
bool dominates (const ObjectiveVector & _objectiveVector) const
{
for (unsigned int i = 0; i<size(); i++)
{
// if _objectiveVector is dominated by the ith individual of the archive...
if ( comparator(_objectiveVector, operator[](i).objectiveVector()) )
{
return true;
}
}
return false;
}
/**
* Returns true if the current archive already contains a solution with the same objective values than _objectiveVector
* @param _objectiveVector the objective vector to compare with the current archive
*/
bool contains (const ObjectiveVector & _objectiveVector) const
{
for (unsigned int i = 0; i<size(); i++)
{
if (operator[](i).objectiveVector() == _objectiveVector)
{
return true;
}
}
return false;
}
/**
* Updates the archive with a given individual _moeo
* @param _moeo the given individual
* @return if the _moeo is added to the archive
*/
virtual bool operator()(const MOEOT & _moeo) = 0;
/**
* Updates the archive with a given population _pop
* @param _pop the given population
* @return if at least one _pop[i] is added to the archive
*/
virtual bool operator()(const eoPop < MOEOT > & _pop) = 0;
/**
* Returns true if the current archive contains the same objective vectors than the given archive _arch
* @param _arch the given archive
*/
bool equals (const moeoFuzzyArchive < MOEOT > & _arch)
{
for (unsigned int i=0; i<size(); i++)
{
if (! _arch.contains(operator[](i).objectiveVector()))
{
return false;
}
}
for (unsigned int i=0; i<_arch.size() ; i++)
{
if (! contains(_arch[i].objectiveVector()))
{
return false;
}
}
return true;
}
protected:
/**
* Updates the archive with a given individual _moeo
* @param _moeo the given individual
*/
bool update(const MOEOT & _moeo)
{
// first step: removing the dominated solutions from the archive
for (unsigned int j=0; j<size();)
{
// if the jth solution contained in the archive is dominated by _moeo
if ( comparator(operator[](j).objectiveVector(), _moeo.objectiveVector()) )
{
operator[](j) = back();
pop_back();
}
else if (replace && (_moeo.objectiveVector() == operator[](j).objectiveVector()))
{
operator[](j) = back();
pop_back();
}
else
{
j++;
}
}
// second step: is _moeo dominated?
bool dom = false;
for (unsigned int j=0; j<size(); j++)
{
// if _moeo is dominated by the jth solution contained in the archive
if ( comparator(_moeo.objectiveVector(), operator[](j).objectiveVector()) )
{
dom = true;
break;
}
else if (!replace && (_moeo.objectiveVector() == operator[](j).objectiveVector()) )
{
dom = true;
break;
}
}
return !dom;
}
/**
* Updates the archive with a given population _pop
* @param _pop the given population
*/
bool update(const eoPop < MOEOT > & _pop)
{
bool res = false;
bool tmp = false;
for (unsigned int i=0; i<_pop.size(); i++)
{
tmp = (*this).update(_pop[i]);
res = tmp || res;
}
return res;
}
/** A comparator based on fuzzy Pareto dominance (used as default) */
moeoFuzzyParetoComparator < ObjectiveVector > FuzzyComparator;
/** boolean */
bool replace;
};
#endif /*MOEOFUZZYARCHIVE_H_ */

View file

@ -0,0 +1,118 @@
/*
<moeoFuzzyParetoComparator.h>
Oumayma BAHRI
Author:
Oumayma BAHRI <oumaymabahri.com>
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOFUZZYPARETOCOMPARATOR_H_
#define MOEOFUZZYPARETOCOMPARATOR_H_
#include <comparator/moeoObjectiveVectorComparator.h>
//#include "triple.h"
/**
* This class allows ranking fuzzy-valued objectives according to new dominance relations.
The dominance is defined between vectors of triangular fuzzy numbers (each number is expressed by a triplet of values [first, second, third].
*/
template < class ObjectiveVector >
class moeoFuzzyParetoObjectiveVectorComparator : public moeoObjectiveVectorComparator < ObjectiveVector >
{
int compareTriangNum (std::triple<double, double, double> A, std::triple<double, double, double> B)
{
// Total dominance
if (A.third < B.first) return TNCR_TOTAL_DOMINANCE;
// Partial Strong dominance
if (A.third >= B.first && A.second <= B.first && A.third <= B.second) return TNCR_PARTIAL_STRONG_DOMINANCE;
// Partial Weak dominance
if ((A.first <B.first && A.third < B.third) &&
( (A.second <= B.first && A.third > B.second) || (A.second > B.first && A.third <= B.second ) || (A.second > B.first && A.third > B.second )))
return TNCR_PARTIAL_WEAK_DOMINANCE;
if (A.first < B.first && A.third >= B.third && A.second < B.second)
return TNCR_PARTIAL_WEAK_DOMINANCE;
else if (A.first < B.first && A.third >= B.third && A.second >= B.second && (B.first - A.first) > (B.third - A.third))
return TNCR_PARTIAL_WEAK_DOMINANCE;
return 0;
}
public:
/**
* Returns true if _objectiveVector1 V1 is dominated by _objectiveVector2 V2 means V2 dominates V1
* @param _objectiveVector1 the first objective vector
* @param _objectiveVector2 the second objective vector
*/
/*const*/ bool operator()(const ObjectiveVector & _objectiveVector1, const ObjectiveVector & _objectiveVector2)
{
bool dom = false;
int nb_Different_Objective_Values = 0,
nb_Total_Dominance = 0,
nb_Partial_Strong_Dominance = 0,
nb_Partial_Weak_Dominance = 0,
nb_Other = 0;
//nObjective= 2
for (unsigned int i=0; i<ObjectiveVector::nObjectives(); i++)
{
// first, we have to check if the 2 objective values are not equal for the ith objective
if (( fabs(_objectiveVector1[i].first - _objectiveVector2[i].first) > ObjectiveVector::Traits::tolerance())||
( fabs(_objectiveVector1[i].second - _objectiveVector2[i].second) > ObjectiveVector::Traits::tolerance())||
( fabs(_objectiveVector1[i].third - _objectiveVector2[i].third) > ObjectiveVector::Traits::tolerance()))
{
nb_Different_Objective_Values++;
// if the ith objective have to be minimized...
if (ObjectiveVector::minimizing(i))
{
if ( compareTriangNum(_objectiveVector2[i], _objectiveVector1[i] ) == TNCR_TOTAL_DOMINANCE ) nb_Total_Dominance++;
else if ( compareTriangNum(_objectiveVector2[i], _objectiveVector1[i] ) == TNCR_PARTIAL_STRONG_DOMINANCE ) nb_Partial_Strong_Dominance++;
else if ( compareTriangNum(_objectiveVector2[i], _objectiveVector1[i] ) == TNCR_PARTIAL_WEAK_DOMINANCE ) nb_Partial_Weak_Dominance++;
else nb_Other++;
}
else
{
// Develop the maximizing compareTriangNum version
}
}
}
// Strong Pareto Dominance
if ( nb_Different_Objective_Values == nb_Total_Dominance ||
nb_Different_Objective_Values == nb_Partial_Strong_Dominance ||
nb_Total_Dominance >= 1 && nb_Partial_Strong_Dominance > 0 ||
nb_Total_Dominance >= 1 || nb_Partial_Strong_Dominance >= 1 && nb_Partial_Weak_Dominance > 0)
{ dom = true;
}
else if ( nb_Different_Objective_Values == nb_Partial_Weak_Dominance ) { dom = true; }
else {return false;
}
return dom;
}
enum TriangularNumberComparaisonResult
{
TNCR_TOTAL_DOMINANCE,
TNCR_PARTIAL_STRONG_DOMINANCE,
TNCR_PARTIAL_WEAK_DOMINANCE
};
};
#endif /*MOEOFUZZYPARETOCOMPARATOR_H_*/

View file

@ -0,0 +1,125 @@
/*
<moeoFuzzyRealObjectiveVector.h>
Oumayma BAHRI
Author:
Oumayma BAHRI <oumaymabahri.com>
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOFUZZYREALOBJECTIVEVECTOR_H_
#define MOEOFUZZYREALOBJECTIVEVECTOR_H_
#include <iostream>
#include <math.h>
#include <comparator/moeoObjectiveObjectiveVectorComparator.h>
#include <comparator/moeoFuzzyParetoComparator.h>
//#include "triple.h"
/*
*This class allows to represent a solution in the objective space (phenotypic representation) by a std::vector of triangles,
* i.e. that an objective value is represented using a triangle of double, and this for any objective.
*/
template < class ObjectiveVectorTraits >
class moeoFuzzyRealObjectiveVector : public moeoObjectiveVector < ObjectiveVectorTraits, std::triple<double, double, double> >
{
public:
using moeoObjectiveVector < ObjectiveVectorTraits, std::triple<double,double,double> >::size;
using moeoObjectiveVector < ObjectiveVectorTraits, std::triple<double,double,double> >::operator[];
/**
* Ctor
*/
moeoFuzzyRealObjectiveVector()
{}
/**
* Ctor from a vector of triangles of doubles
* @param _v the std::vector < std::triple<double, double, double> >
*/
moeoFuzzyRealObjectiveVector(std::vector < std::triple<double,double,double> > & _v) : moeoObjectiveVector < ObjectiveVectorTraits, std::triple<double,double,double> > (_v)
{}
/**
* Returns true if the current objective vector dominates _other according to the Fuzzy Preto dominance relation
* (but it's better to use a moeoObjectiveVectorComparator object to compare solutions)
* @param _other the other FuzzyRealObjectiveVector object to compare with
*/
bool dominates(const moeoFuzzyRealObjectiveVector < ObjectiveVectorTraits > & _other) const
{
moeoFuzzyParetoComparator < moeoFuzzyRealObjectiveVector<ObjectiveVectorTraits> > comparator;
return comparator(_other, *this);
}
/**
* Returns true if the current objective vector is equal to _other (according to a tolerance value)
* @param _other the other FuzzyRealObjectiveVector object to compare with
*/
bool operator==(const moeoFuzzyRealObjectiveVector < ObjectiveVectorTraits > & _other) const
{
for (unsigned int i=0; i < size(); i++)
{
if ( (fabs((operator[](i)).first - _other[i].first) > ObjectiveVectorTraits::tolerance()) &&
(fabs((operator[](i)).second - _other[i].second) > ObjectiveVectorTraits::tolerance()) &&
(fabs((operator[](i)).third - _other[i].third) > ObjectiveVectorTraits::tolerance()) )
{
return false;
}
}
return true;
}
/**
* Returns true if the current objective vector is different than _other (according to a tolerance value)
* @param _other the other FuzzyRealObjectiveVector object to compare with
*/
bool operator!=(const moeoFuzzyRealObjectiveVector < ObjectiveVectorTraits > & _other) const
{
return ! operator==(_other);
}
};
/**
* Output for a FuzzyRealObjectiveVector object
* @param _os output stream
* @param _objectiveVector the objective vector to write
*/
template < class ObjectiveVectorTraits >
std::ostream & operator<<(std::ostream & _os, const moeoFuzzyRealObjectiveVector < ObjectiveVectorTraits > & _objectiveVector)
{
for (unsigned int i=0; i<_objectiveVector.size()-1; i++)
_os << "[" << _objectiveVector[i].first << " " << _objectiveVector[i].second << " " << _objectiveVector[i].third << "]" <<" ";
_os << "[" <<_objectiveVector[_objectiveVector.size()-1].first << " " << _objectiveVector[_objectiveVector.size()-1].second
<< " " << _objectiveVector[_objectiveVector.size()-1].third << "]" << " ";
return _os;
}
/**
* Input for a FuzzyRealObjectiveVector object
* @param _is input stream
* @param _objectiveVector the objective vector to read
*/
template < class ObjectiveVectorTraits >
std::istream & operator>>(std::istream & _is, moeoFuzzyRealObjectiveVector < ObjectiveVectorTraits > & _objectiveVector)
{
for (unsigned int i=0; i<_objectiveVector.size(); i++)
{
_is >> _objectiveVector[i].first >> _objectiveVector[i].second >> _objectiveVector[i].third;
}
return _is;
}
#endif /*MOEOFUZZYREALOBJECTIVEVECTOR_H_*/

View file

@ -1,95 +0,0 @@
/*
<BertDistance.h>
Oumayma BAHRI
Author:
Oumayma BAHRI <oumaymabahri.com>
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef BERTDISTANCE_H_
#define BERTDISTANCE_H_
#include <math.h>
#include <distance/moeoObjSpaceDistance.h>
#include "ObjectiveVectorNormalizer.h"
/**
* A class allowing to compute an Bert distance between two fuzzy solutions in the objective space
with normalized objective values (i.e. between 0 and 1).
* A distance value then lies between 0 and sqrt(nObjectives).
*/
template < class MOEOT>
class BertDistance : public moeoObjSpaceDistance < MOEOT >
{
public:
/** the objective vector type of the solutions */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/** the fitness type of the solutions */
typedef typename MOEOT::Fitness Fitness;
/**
default ctr
*/
/* BertDistance ()
{}*/
/**
ctr with a normalizer
@param _normalizer the normalizer used for every ObjectiveVector
*/
/**
default ctr
*/
BertDistance ():normalizer(defaultNormalizer)
{}
double calculateBertDistance(std::triple<double, double, double> A, std::triple<double, double, double> B)
{
double midA = 0.5 * (A.first + A.third);
double midB = 0.5 * (B.first + B.third);
double sprA = 0.5 * (A.first - A.third);
double sprB = 0.5 * (B.first - B.third);
double theta = 0.5;
return sqrt((midA -midB) * (midA -midB) + theta * (sprA - sprB) * (sprA - sprB));
}
/**
* tmp1 and tmp2 take the Expected values of Objective vectors
* Returns the Bert distance between _obj1 and _obj2 in the objective space
* @param _obj1 the first objective vector
* @param _obj2 the second objective vector
*/
const Fitness operator()(const ObjectiveVector & _obj1, const ObjectiveVector & _obj2)
{
vector<double> v_BD;
double dist=0.0;
for (unsigned int i=0; i<ObjectiveVector::nObjectives(); i++)
{
dist +=calculateBertDistance(normalizer(_obj1)[i], normalizer(_obj2)[i]);
}
//dist += normalizer(v_BD);
return dist/ObjectiveVector::nObjectives();
}
private:
ObjectiveVectorNormalizer<MOEOT> Normalizer;
};
#endif /*BERTDISTANCE_H_*/

View file

@ -16,12 +16,11 @@ Contact: paradiseo-help@lists.gforge.inria.fr
#include <math.h>
#include <distance/moeoObjSpaceDistance.h>
#include "ObjectiveVectorNormalizer.h"
#include <utils/moeoFuzzyObjectiveVectorNormalizer.h>
/**
* A class allowing to compute an Bert distance between two fuzzy solutions in the objective space
with normalized objective values (i.e. between 0 and 1).
* A distance value then lies between 0 and sqrt(nObjectives).
* A class allowing to compute the bertoluzza distance between two fuzzy solutions in the objective space with normalized objective values.
* A distance value lies between 0 and sqrt(nObjectives).
*/
template < class MOEOT>
class moeoBertDistance : public moeoObjSpaceDistance < MOEOT >
@ -86,7 +85,7 @@ const Fitness operator()(const ObjectiveVector & _obj1, const ObjectiveVector &
private:
ObjectiveVectorNormalizer<MOEOT> Normalizer;
moeoFuzzyObjectiveVectorNormalizer<MOEOT> Normalizer;

View file

@ -0,0 +1,66 @@
/*
<moeoExpectedFuzzyDistance.h>
Oumayma BAHRI
Author:
Oumayma BAHRI <oumaymabahri.com>
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOEXPECTEDFUZZYDISTANCE_H_
#define MOEOEXPECTEDFUZZYDISTANCE_H_
#include <math.h>
#include <distance/moeoObjSpaceDistance.h>
#include <utils/moeoFuzzyObjectiveVectorNormalizer.h>
/**
* An expected euclidian distance between two fuzzy solutions in the objective space
* Every solution value is expressed by a triangular fuzzy number
*/
template < class MOEOT>
class moeoExpectedFuzzyDistance : public moeoObjSpaceDistance < MOEOT >
{
public:
/** the objective vector type of the solutions */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/** the fitness type of the solutions */
typedef typename MOEOT::Fitness Fitness;
/**
default ctr
*/
moeoExpectedFuzzyDistance ()
{}
/**
* tmp1 and tmp2 take the Expected values of Objective vectors
* Returns the expected distance between _obj1 and _obj2 in the objective space
* @param _obj1 the first objective vector
* @param _obj2 the second objective vector
*/
const Fitness operator()(const ObjectiveVector & _obj1, const ObjectiveVector & _obj2)
{
Fitness result = 0.0;
Fitness tmp1, tmp2;
for (unsigned int i=0; i<ObjectiveVector::nObjectives(); i++)
{
tmp1 = ((_obj1)[i].first + (_obj1)[i].third + 2 *(_obj1)[i].second ) /4 ;
tmp2 = ((_obj2)[i].first + (_obj2)[i].third + 2* (_obj2)[i].second ) /4 ;
result += (tmp1-tmp2) * (tmp1-tmp2);
}
return sqrt(result);
}
};
#endif /*MOEOEXPECTEDFUZZYDISTANCE_H_*/

View file

@ -0,0 +1,152 @@
/*
<moeoFuzzyCrowdingDiversity.h>
Oumayma BAHRI
Author:
Oumayma BAHRI <oumaymabahri.com>
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOFUZZYCROWDINGDIVERSITY_H_
#define MOEOFUZZYCROWDINGDIVERSITY_H_
#include <eoPop.h>
#include <diversity/moeoDiversityAssignment.h>
#include <comparator/moeoOneObjectiveComparator.h>
#include <comparator/moeoFuzzyParetoComparator.h>
#include <distance/moeoExpectedFuzzyDistance.h>
/**
* Diversity assignment sheme based on crowding proposed in:
* K. Deb, A. Pratap, S. Agarwal, T. Meyarivan, "A Fast and Elitist Multi-Objective Genetic Algorithm: NSGA-II", IEEE Transactions on Evolutionary Computation, vol. 6, no. 2 (2002).
* Tis strategy assigns diversity values FRONT BY FRONT. It is, for instance, used in NSGA-II.
*/
template < class MOEOT >
class moeoFuzzyCrowdingDiversity : public CrowdingDiversityAssignment < MOEOT >
{
public:
/** the objective vector type of the solutions */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Updates the diversity values of the whole population _pop by taking the deletion of the objective vector _objVec into account.
* @param _pop the population
* @param _objVec the objective vector
*/
void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec)
{
std::cout << "WARNING : updateByDeleting not implemented in FrontByFrontCrowdingDistanceDiversityAssignment" << std::endl;
}
private:
using CrowdingDiversityAssignment < MOEOT >::inf;
using CrowdingDiversityAssignment < MOEOT >::tiny;
/**
* Sets the distance values
* @param _pop the population
*/
void setDistances (eoPop <MOEOT> & _pop)
{
unsigned int a,b;
double min, max, distance;
unsigned int nObjectives = MOEOT::ObjectiveVector::nObjectives();
// set diversity to 0 for every individual
for (unsigned int i=0; i<_pop.size(); i++)
{
_pop[i].diversity(0.0);
}
// sort the whole pop according to fitness values
moeoFitnessThenDiversityComparator < MOEOT > fitnessComparator;
std::vector<MOEOT *> sortedptrpop;
sortedptrpop.resize(_pop.size());
// due to intensive sort operations for this diversity assignment,
// it is more efficient to perform sorts using only pointers to the
// population members in order to avoid copy of individuals
for(unsigned int i=0; i< _pop.size(); i++) sortedptrpop[i] = & (_pop[i]);
//sort the pointers to population members
moeoFuzzyParetoComparator<MOEOT> comp( fitnessComparator);
std::sort(sortedptrpop.begin(), sortedptrpop.end(), comp);
// compute the expected crowding distance values for every individual "front" by "front" (front : from a to b)
a = 0; // the front starts at a
while (a < _pop.size())
{
b = lastIndex(sortedptrpop,a); // the front ends at b
//b = lastIndex(_pop,a); // the front ends at b
// if there is less than 2 individuals in the front...
if ((b-a) < 2)
{
for (unsigned int i=a; i<=b; i++)
{
sortedptrpop[i]->diversity(inf());
//_pop[i].diversity(inf());
}
}
// else...
else
{
// for each objective
for (unsigned int obj=0; obj<nObjectives; obj++)
{
// sort in the descending order using the values of the objective 'obj'
moeoOneObjectiveComparator < MOEOT > objComp(obj);
moeoFuzzyParetoComparator<MOEOT> comp( objComp );
std::sort(sortedptrpop.begin(), sortedptrpop.end(), comp);
// min & max
min = (sortedptrpop[b])->objectiveVector()[obj].second;
max = (sortedptrpop[a])->objectiveVector()[obj].second;
// avoid extreme case
if (min == max)
{
min -= tiny();
max += tiny();
}
// set the diversity value to infiny for min and max
sortedptrpop[a]->diversity(inf());
sortedptrpop[b]->diversity(inf());
// set the diversity values for the other individuals
for (unsigned int i=a+1; i<b; i++)
{
distance = ( sortedptrpop[i-1]->moeoExpectedFuzzyDistance(objectiveVector()[obj]) - sortedptrpop[i+1]->moeoExpectedFuzzyDistance(objectiveVector()[obj] )) / (max-min);
sortedptrpop[i]->diversity(sortedptrpop[i]->diversity() + distance);
}
}
}
// go to the next front
a = b+1;
}
}
/**
* Returns the index of the last individual having the same fitness value than _pop[_start]
* @param _pop the vector of pointers to population individuals
* @param _start the index to start from
*/
unsigned int lastIndex (std::vector<MOEOT *> & _pop, unsigned int _start)
{
unsigned int i=_start;
while ( (i<_pop.size()-1) && (_pop[i]->fitness()==_pop[i+1]->fitness()) )
{
i++;
}
return i;
}
};
#endif /*MOEOFUZZYCROWDINGDIVERSITY_H_*/

View file

@ -0,0 +1,116 @@
/*
<moeoFuzzyNearestNeighborDiversity.h>
Oumayma BAHRI
Author:
Oumayma BAHRI <oumaymabahri.com>
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOFUZZYNEARESTNEIGHBORDIVERSITY_H_
#define MOEOFUZZYNEARESTNEIGHBORDIVERSITY_H_
#include <list>
#include <diversity/moeoDiversityAssignment.h>
#include <archive/moeoFuzzyArchive.h>
#include <distance/moeoBertDistance.h>
/**
* moeoFuzzyNearestNeighborDiversity is a moeoDiversityAssignment using the fuzzy "Bert" distance between individuals to assign diversity.
*/
template < class MOEOT >
class moeoFuzzyNearestNeighborDiversity : public moeoDiversityAssignment < MOEOT >
{
public:
/** The type for objective vector */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Ctor where you can choose your own distance and archive
* @param _dist the distance used
* @param _archive the archive used
* @param _index index for find the k-ieme nearest neighbor, _index correspond to k
*/
moeoFuzzyNearestNeighborDiversity(moeoBertDistance <MOEOT, double>& _dist, moeoFuzzyArchive <MOEOT>& _archive, unsigned int _index=1) : distance(_dist), archive(_archive), index(_index)
{}
/**
* Affect the diversity to the pop, diversity corresponding to the k-ieme nearest neighbor.
* @param _pop the population
*/
void operator () (eoPop < MOEOT > & _pop)
{
unsigned int i = _pop.size();
unsigned int j = archive.size();
double tmp=0;
std::vector< std::list<double> > matrice(i+j);
if (i+j>0)
{
for (unsigned k=0; k<i+j-1; k++)
{
for (unsigned l=k+1; l<i+j; l++)
{
if ( (k<i) && (l<i) )
tmp=distance(_pop[k], _pop[l]);
else if ( (k<i) && (l>=i) )
tmp=distance(_pop[k], archive[l-i]);
else
tmp=distance(archive[k-i], archive[l-i]);
matrice[k].push_back(tmp);
matrice[l].push_back(tmp);
}
}
}
for (unsigned int k=0; k<i+j; k++)
matrice[k].sort();
for (unsigned int k=0; k<i; k++)
_pop[k].diversity(-1 * 1/(2+getElement(matrice[k])));
for (unsigned int k=i; k<i+j; k++)
archive[k-i].diversity(-1 * 1/(2+getElement(matrice[k])));
}
/**
* Updates the diversity values of the whole population _pop by taking the deletion of the objective vector _objVec into account.
* @param _pop the population
* @param _objVec the objective vector
*/
void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec)
{
std::cout << "WARNING : updateByDeleting not implemented in moeoNearestNeighborDiversityAssignment" << std::endl;
}
private:
/** Default distance */
moeoBertDistance < MOEOT > Distance;
/** Default archive */
moeoFuzzyArchive < MOEOT > Archive;
/** the index corresponding to k for search the k-ieme nearest neighbor */
unsigned int index;
/**
* Return the index-th element of the list _myList
* @param _myList the list which contains distances
*/
double getElement(std::list<double> _myList)
{
std::list<double>::iterator it= _myList.begin();
for (unsigned int i=1; i< std::min((unsigned int)_myList.size(),index); i++)
it++;
return *it;
}
};
#endif /*MOEOFUZZYNEARESTNEIGHBORDIVERSITY_H_*/

View file

@ -0,0 +1,75 @@
/*
<moeoFuzzyObjectiveVectorNormalizer.h>
Oumayma BAHRI
Author:
Oumayma BAHRI <oumaymabahri.com>
ParadisEO WebSite : http://paradiseo.gforge.inria.fr
Contact: paradiseo-help@lists.gforge.inria.fr
*/
//-----------------------------------------------------------------------------
#ifndef MOEOFUZZYOBJECTIVEVECTORNORMALIZER_H_
#define MOEOFUZZYOBJECTIVEVECTORNORMALIZER_H_
#include <eoPop.h>
#include <utils/eoRealBounds.h>
/**
Adaptation of classical class "moeoObjectiveVectorNormalizer" to normalize fuzzy objective Vectors
*/
template <class MOEOT>
class moeoFuzzyObjectiveVectorNormalizer
{
public:
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
typedef typename MOEOT::ObjectiveVector::Type Type;
typedef typename std::vector<std::vector<Type> > Scale;
typedef eoRealInterval Bounds;
/**
constructor with a supplied scale, usefull if you tweak your scale
@param _scale the scale for noramlzation
@param max_param the returned values will be between 0 and max
*/
moeoFuzzyObjectiveVectorNormalizer(Scale _scale=make_dummy_scale(),Type max_param=100):scale(_scale),max(max_param)
{}
/**
* main fonction, normalize a triangular fuzzy vector defined with a triplet [first, second, third].
* @param _vec the vector
* @return the normalized vector
*/
virtual ObjectiveVector operator()(const ObjectiveVector &_vec){
unsigned int dim=_vec.nObjectives();
ObjectiveVector res;
for (unsigned int i=0;i<dim;i++){
res[i].first=(_vec[i].first-scale[i][1])*scale[i][0];
res[i].second=(_vec[i].second-scale[i][1])*scale[i][0];
res[i].third=(_vec[i].third-scale[i][1])*scale[i][0];
}
return res;
}
/**
normalize a population
@param pop the population to normalize
@return a vector of normalized Objective vectors
*/
static std::vector<ObjectiveVector> normalize(const eoPop<MOEOT> &pop, Type &max){
moeoFuzzyObjectiveVectorNormalizer normalizer(pop,true, max);
return normalizer(pop);
}
private:
Scale scale;
Type max;
};
#endif