This commit is contained in:
LPTK 2013-06-11 14:10:23 +02:00
commit d77815cd11
18 changed files with 1096 additions and 255 deletions

View file

@ -1,3 +1,5 @@
today=`date --iso-8601`
git archive --format zip master > paradisEO-${today}.zip
name=paradiseo_$today
git archive --prefix=$name/ --format zip master > $name.zip
echo $name.zip

View file

@ -31,17 +31,12 @@ endif()
### 0) Define general CXX flags for DEBUG and RELEASE
######################################################################################
#if(DEBUG)
# set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "" FORCE)
#else(DEBUG)
# set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
#endif(DEBUG)
add_definitions(-DDEPRECATED_MESSAGES)
set(CMAKE_CXX_FLAGS_DEBUG "-Wunknown-pragmas -O0 -g -Wall -Wextra -ansi -pedantic" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "-Wunknown-pragmas -O2" CACHE STRING "" FORCE)
if(SMP)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11 -pthread" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11 -pthread" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11 -pthread" CACHE STRING "" FORCE)
add_definitions(-D_GLIBCXX_USE_NANOSLEEP)

View file

@ -81,10 +81,24 @@ public:
* Unfeasible by default
*/
eoDualFitness() :
_value(),
_value(0.0),
_is_feasible(false)
{}
//! Initialization with only the value, the fitness will be unfeasible.
/*!
* WARNING: this is what is used when you initialize a new fitness from a double.
* Unfeasible by default
*/
template<class T>
eoDualFitness( T value ) :
_value(value),
_is_feasible(false)
{
assert( _value == 0 );
}
//! Copy constructor
eoDualFitness(const eoDualFitness& other) :
_value(other._value),
@ -108,12 +122,11 @@ public:
* type, if needed. For example, this is possible:
* eoDualFitness<double,std::less<double> > fit;
* double val = 1.0;
* fit = val;
* val = fit;
*/
operator BaseType(void) const { return _value; }
operator BaseType(void) const { return _value; }
inline bool is_feasible() const
{
return _is_feasible;
@ -125,16 +138,16 @@ public:
}
//! Copy operator from a std::pair
eoDualFitness& operator=(const std::pair<BaseType,bool>& v)
eoDualFitness& operator=( const std::pair<BaseType, bool>& v )
{
_value = v.first;
_is_feasible = v.second;
this->_value = v.first;
this->_is_feasible = v.second;
return *this;
}
//! Copy operator from another eoDualFitness
template <class F, class Cmp>
eoDualFitness<F,Cmp> & operator=(const eoDualFitness<BaseType, Compare>& other )
eoDualFitness<BaseType,Compare> & operator=( const eoDualFitness<BaseType, Compare>& other )
{
if (this != &other) {
this->_value = other._value;
@ -143,6 +156,17 @@ public:
return *this;
}
/*
//! Copy operator from a scalar
template<class T>
eoDualFitness& operator=(const T v)
{
this->_value = v;
this->_is_feasible = false;
return *this;
}
*/
//! Comparison that separate feasible individuals from unfeasible ones. Feasible are always better
/*!
* Use less as a default comparison operator
@ -183,69 +207,137 @@ public:
public:
/* FIXME it would be better to raise errors (or warnings) if one try to apply arithmetics operators between feasible
* and unfeasible fitnesses. This necessitates to add wrappers for operators that aggregates sets of dual fitnesses
* (like eoStat), both for separating feasibility and for aggregating them.
*/
// NOTE: we cannot declare this set of operator classes as friend, because there is two differerent templated classes declared later
// (for minimizing and maximizing)
//! Add a given fitness to the current one
template <class F, class Cmp>
friend
eoDualFitness<F,Cmp> & operator+=( eoDualFitness<F,Cmp> & from, const eoDualFitness<F,Cmp> & that )
template<class T>
eoDualFitness<BaseType,Compare> & operator+=( const T that )
{
from._value += that._value;
this->_value += that;
return *this;
}
//! Add a given fitness to the current one
eoDualFitness<BaseType,Compare> & operator+=( const eoDualFitness<BaseType,Compare> & that )
{
// from._value += that._value;
this->_value += that._value;
// true only if the two are feasible, else false
from._is_feasible = from._is_feasible && that._is_feasible;
// from._is_feasible = from._is_feasible && that._is_feasible;
this->_is_feasible = this->_is_feasible && that._is_feasible;
return from;
return *this;
}
//! Substract a given fitness to the current one
template <class F, class Cmp>
friend
eoDualFitness<F,Cmp> & operator-=( eoDualFitness<F,Cmp> & from, const eoDualFitness<F,Cmp> & that )
template<class T>
eoDualFitness<BaseType,Compare> & operator-=( const T that )
{
from._value -= that._value;
this->_value -= that;
return *this;
}
//! Substract a given fitness to the current one
eoDualFitness<BaseType,Compare> & operator-=( const eoDualFitness<BaseType,Compare> & that )
{
this->_value -= that._value;
// true only if the two are feasible, else false
from._is_feasible = from._is_feasible && that._is_feasible;
this->_is_feasible = this->_is_feasible && that._is_feasible;
return from;
return *this;
}
//! Add a given fitness to the current one
template<class T>
eoDualFitness<BaseType,Compare> & operator/=( T that )
{
this->_value /= that;
return *this;
}
//! Add a given fitness to the current one
eoDualFitness<BaseType,Compare> & operator/=( const eoDualFitness<BaseType,Compare> & that )
{
this->_value /= that._value;
// true only if the two are feasible, else false
this->_is_feasible = this->_is_feasible && that._is_feasible;
return *this;
}
template<class T>
eoDualFitness<BaseType,Compare> operator+( T that )
{
this->_value += that;
return *this;
}
// Add this fitness's value to that other, and return a _new_ instance with the result.
template <class F, class Cmp>
eoDualFitness<F,Cmp> operator+(const eoDualFitness<F,Cmp> & that)
eoDualFitness<BaseType,Compare> operator+( const eoDualFitness<BaseType,Compare> & that )
{
eoDualFitness<F,Cmp> from( *this );
eoDualFitness<BaseType,Compare> from( *this );
return from += that;
}
// Add this fitness's value to that other, and return a _new_ instance with the result.
template <class F, class Cmp>
eoDualFitness<F,Cmp> operator-(const eoDualFitness<F,Cmp> & that)
template<class T>
eoDualFitness<BaseType,Compare> operator-( T that )
{
eoDualFitness<F,Cmp> from( *this );
this->_value -= that;
return *this;
}
// Add this fitness's value to that other, and return a _new_ instance with the result.
eoDualFitness<BaseType,Compare> operator-( const eoDualFitness<BaseType,Compare> & that )
{
eoDualFitness<BaseType,Compare> from( *this );
return from -= that;
}
//! Print an eoDualFitness instance as a pair of numbers, separated by a space
template <class F, class Cmp>
friend
std::ostream& operator<<(std::ostream& os, const eoDualFitness<F, Cmp>& f)
template<class T>
eoDualFitness<BaseType,Compare> operator/( T that )
{
os << f._value << " " << f._is_feasible;
this->_value /= that;
return *this;
}
// Add this fitness's value to that other, and return a _new_ instance with the result.
eoDualFitness<BaseType,Compare> operator/( const eoDualFitness<BaseType,Compare> & that )
{
eoDualFitness<BaseType,Compare> from( *this );
return from /= that;
}
//! Print an eoDualFitness instance as a pair of numbers, separated by a space
friend
std::ostream& operator<<( std::ostream& os, const eoDualFitness<BaseType,Compare> & fitness )
{
os << fitness._value << " " << fitness._is_feasible;
return os;
}
//! Read an eoDualFitness instance as a pair of numbers, separated by a space
template <class F, class Cmp>
friend
std::istream& operator>>(std::istream& is, eoDualFitness<F, Cmp>& f)
std::istream& operator>>( std::istream& is, eoDualFitness<BaseType,Compare> & fitness )
{
F value;
BaseType value;
is >> value;
bool feasible;
is >> feasible;
f = std::make_pair<F,bool>( value, feasible );
fitness._value = value;
fitness._is_feasible = feasible;
return is;
}
};

View file

@ -155,7 +155,7 @@ namespace eoserial
inline void unpackBasePushBack( const Entity* obj, T& container )
{
const Array* arr = static_cast<const Array*>( obj );
for( auto it = arr->begin(), end = arr->end();
for( Array::const_iterator it = arr->begin(), end = arr->end();
it != end;
++it )
{
@ -190,7 +190,7 @@ namespace eoserial
inline void unpackBase( const Entity* entity, std::map<std::string, T> & m )
{
const Object* obj = static_cast< const Object* >( entity );
for( auto it = obj->begin(), end = obj->end();
for( Object::const_iterator it = obj->begin(), end = obj->end();
it != end;
++it )
{
@ -298,7 +298,7 @@ namespace eoserial
inline Entity* packIterable( const T& container )
{
Array* arr = new Array;
for( auto it = container.begin(), end = container.end();
for( Array::const_iterator it = container.begin(), end = container.end();
it != end;
++it )
{
@ -332,7 +332,7 @@ namespace eoserial
inline Entity* pack( const std::map<std::string, T>& map )
{
Object* obj = new Object;
for( auto it = map.begin(), end = map.end();
for( Object::const_iterator it = map.begin(), end = map.end();
it != end;
++it )
{

View file

@ -27,9 +27,12 @@
#ifndef _eoRealBounds_h
#define _eoRealBounds_h
#include <cassert>
#include <sstream>
#include <stdexcept> // std::exceptions!
#include <utils/eoRNG.h>
#include "eoLogger.h"
/**
\defgroup Real Vector of reals
@ -231,7 +234,7 @@ public :
assert( repRange >= 0 );
#ifndef NDEBUG
if( repRange == 0 ) {
eo::log << eo::warnings << "Null range in eoRealBounds (min=" << _min << ", max=" << _max << ")" << std::endl;
eo::log << eo::warnings << "Warning: null range in eoRealBounds (min=" << _min << ", max=" << _max << ")" << std::endl;
}
#endif
}

View file

@ -80,7 +80,20 @@ public:
* @param _kappa scaling factor kappa
*/
moeoIBEA (unsigned int _maxGen, eoEvalFunc < MOEOT > & _eval, eoQuadOp < MOEOT > & _crossover, double _pCross, eoMonOp < MOEOT > & _mutation, double _pMut, moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > & _metric, const double _kappa=0.05) :
defaultGenContinuator(_maxGen), continuator(defaultGenContinuator), eval(_eval), defaultPopEval(_eval), popEval(defaultPopEval), select (2), selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(_crossover, _pCross, _mutation, _pMut), genBreed (select, defaultSGAGenOp), breed (genBreed), fitnessAssignment(_metric, _kappa), replace (fitnessAssignment, diversityAssignment)
defaultGenContinuator(_maxGen),
continuator(defaultGenContinuator),
eval(_eval),
defaultPopEval(_eval),
popEval(defaultPopEval),
select (2),
selectMany(select,0.0),
selectTransform(defaultSelect, defaultTransform),
defaultSGAGenOp(_crossover, _pCross, _mutation, _pMut),
genBreed (select, defaultSGAGenOp),
breed (genBreed),
default_fitnessAssignment( new moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>(_metric, _kappa) ),
fitnessAssignment(*default_fitnessAssignment),
replace(fitnessAssignment, diversityAssignment)
{}
@ -94,7 +107,7 @@ public:
*/
moeoIBEA (eoContinue < MOEOT > & _continuator, eoEvalFunc < MOEOT > & _eval, eoGenOp < MOEOT > & _op, moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > & _metric, const double _kappa=0.05) :
defaultGenContinuator(0), continuator(_continuator), eval(_eval), defaultPopEval(_eval), popEval(defaultPopEval), select(2),
selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(defaultQuadOp, 1.0, defaultMonOp, 1.0), genBreed(select, _op), breed(genBreed), fitnessAssignment(_metric, _kappa), replace (fitnessAssignment, diversityAssignment)
selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(defaultQuadOp, 1.0, defaultMonOp, 1.0), genBreed(select, _op), breed(genBreed), default_fitnessAssignment( new moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>(_metric, _kappa)), fitnessAssignment(*default_fitnessAssignment), replace (fitnessAssignment, diversityAssignment)
{}
@ -108,7 +121,7 @@ public:
*/
moeoIBEA (eoContinue < MOEOT > & _continuator, eoPopEvalFunc < MOEOT > & _popEval, eoGenOp < MOEOT > & _op, moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > & _metric, const double _kappa=0.05) :
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), genBreed(select, _op), breed(genBreed), fitnessAssignment(_metric, _kappa), replace (fitnessAssignment, diversityAssignment)
selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(defaultQuadOp, 1.0, defaultMonOp, 1.0), genBreed(select, _op), breed(genBreed), default_fitnessAssignment( new moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>(_metric, _kappa)), fitnessAssignment(*default_fitnessAssignment), replace (fitnessAssignment, diversityAssignment)
{}
@ -122,7 +135,7 @@ public:
*/
moeoIBEA (eoContinue < MOEOT > & _continuator, eoEvalFunc < MOEOT > & _eval, eoTransform < MOEOT > & _transform, moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > & _metric, const double _kappa=0.05) :
defaultGenContinuator(0), continuator(_continuator), eval(_eval), defaultPopEval(_eval), popEval(defaultPopEval),
select(2), selectMany(select, 1.0), selectTransform(selectMany, _transform), defaultSGAGenOp(defaultQuadOp, 0.0, defaultMonOp, 0.0), genBreed(select, defaultSGAGenOp), breed(selectTransform), fitnessAssignment(_metric, _kappa), replace(fitnessAssignment, diversityAssignment)
select(2), selectMany(select, 1.0), selectTransform(selectMany, _transform), defaultSGAGenOp(defaultQuadOp, 0.0, defaultMonOp, 0.0), genBreed(select, defaultSGAGenOp), breed(selectTransform), default_fitnessAssignment( new moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>(_metric, _kappa)), fitnessAssignment(*default_fitnessAssignment), replace(fitnessAssignment, diversityAssignment)
{}
@ -136,10 +149,43 @@ public:
*/
moeoIBEA (eoContinue < MOEOT > & _continuator, eoPopEvalFunc < MOEOT > & _popEval, eoTransform < MOEOT > & _transform, moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > & _metric, const double _kappa=0.05) :
defaultGenContinuator(0), continuator(_continuator), eval(defaultEval), defaultPopEval(eval), popEval(_popEval),
select(2), selectMany(select, 1.0), selectTransform(selectMany, _transform), defaultSGAGenOp(defaultQuadOp, 0.0, defaultMonOp, 0.0), genBreed(select, defaultSGAGenOp), breed(selectTransform), fitnessAssignment(_metric, _kappa), replace(fitnessAssignment, diversityAssignment)
select(2), selectMany(select, 1.0), selectTransform(selectMany, _transform), defaultSGAGenOp(defaultQuadOp, 0.0, defaultMonOp, 0.0), genBreed(select, defaultSGAGenOp), breed(selectTransform), default_fitnessAssignment( new moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>(_metric, _kappa)), fitnessAssignment(*default_fitnessAssignment), replace(fitnessAssignment, diversityAssignment)
{}
/**
* Ctor with a eoContinue, a eoPopEval, a eoGenOp and an explicit fitnessAssignment
* @param _continuator stopping criteria
* @param _popEval population evaluation function
* @param _op variation operators
* @param _fitnessAssignment fitness assignment
*/
moeoIBEA (eoContinue < MOEOT > & _continuator, eoPopEvalFunc < MOEOT > & _popEval, eoGenOp < MOEOT > & _op, moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >& _fitnessAssignment) :
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), genBreed(select, _op), breed(genBreed), default_fitnessAssignment(NULL), fitnessAssignment(_fitnessAssignment), replace(fitnessAssignment, diversityAssignment)
{}
/**
* Ctor with a eoContinue, a eoGenOp and an explicit fitnessAssignment
* @param _continuator stopping criteria
* @param _eval evaluation function
* @param _op variation operators
* @param _fitnessAssignment fitness assignment
*/
moeoIBEA (eoContinue < MOEOT > & _continuator, eoEvalFunc < MOEOT > & _eval, eoGenOp < MOEOT > & _op, moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >& _fitnessAssignment) :
defaultGenContinuator(0), continuator(_continuator), eval(_eval), defaultPopEval(_eval), popEval(defaultPopEval), select(2),
selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(defaultQuadOp, 1.0, defaultMonOp, 1.0), genBreed(select, _op), breed(genBreed), default_fitnessAssignment(NULL), fitnessAssignment(_fitnessAssignment), replace(fitnessAssignment, diversityAssignment)
{}
~moeoIBEA()
{
if( default_fitnessAssignment != NULL ) {
delete default_fitnessAssignment;
}
}
/**
* Apply the algorithm to the population _pop until the stopping criteria is satified.
* @param _pop the population
@ -214,7 +260,8 @@ protected:
/** breeder */
eoBreed < MOEOT > & breed;
/** fitness assignment used in IBEA */
moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT > fitnessAssignment;
moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >& fitnessAssignment;
moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >* default_fitnessAssignment;
/** dummy diversity assignment */
moeoDummyDiversityAssignment < MOEOT > diversityAssignment;
/** environmental replacement */

View file

@ -46,32 +46,45 @@
#include <archive/moeoUnboundedArchive.h>
/**
Continues until the optimum ParetoSet level is reached.
Continues until the given ParetoSet level is reached.
@ingroup Continuators
*/
template< class MOEOT>
template< class MOEOT, class MetricT = moeoHyperVolumeDifferenceMetric<typename MOEOT::ObjectiveVector> >
class moeoHypContinue: public eoContinue<MOEOT>
{
public:
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
typedef typename ObjectiveVector::Type AtomType;
/// Ctor
moeoHypContinue( const std::vector<double> & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, double _rho=1.1)
moeoHypContinue( const std::vector<AtomType> & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, double _rho=1.1)
: eoContinue<MOEOT>(), arch(_archive), metric(_normalize,_rho)
{
vectorToParetoSet(_OptimVec);
}
moeoHypContinue( const std::vector<double> & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, ObjectiveVector& _ref_point=NULL)
moeoHypContinue( const std::vector<AtomType> & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, ObjectiveVector& _ref_point=NULL)
: eoContinue<MOEOT> (), arch(_archive), metric(_normalize,_ref_point)
{
vectorToParetoSet(_OptimVec);
}
/** Returns false when a ParetoSet is reached. */
virtual bool operator() ( const eoPop<MOEOT>& _pop )
{
std::vector<ObjectiveVector> bestCurrentParetoSet = pareto( arch );
return is_null_hypervolume( bestCurrentParetoSet );
}
virtual std::string className(void) const { return "moeoHypContinue"; }
protected:
std::vector<ObjectiveVector> pareto( moeoArchive<MOEOT> & _archive )
{
std::vector < ObjectiveVector > bestCurrentParetoSet;
@ -79,7 +92,12 @@ public:
bestCurrentParetoSet.push_back(arch[i].objectiveVector());
}
double hypervolume= metric(bestCurrentParetoSet,OptimSet );
return bestCurrentParetoSet;
}
bool is_null_hypervolume( std::vector<ObjectiveVector>& bestCurrentParetoSet )
{
double hypervolume= metric( bestCurrentParetoSet, OptimSet );
if (hypervolume==0) {
eo::log << eo::logging << "STOP in moeoHypContinue: Best ParetoSet has been reached "
@ -90,7 +108,7 @@ public:
}
/** Translate a vector given as param to the ParetoSet that should be reached. */
void vectorToParetoSet(const std::vector<double> & _OptimVec)
virtual void vectorToParetoSet(const std::vector<AtomType> & _OptimVec)
{
unsigned dim = (unsigned)(_OptimVec.size()/ObjectiveVector::Traits::nObjectives());
OptimSet.resize(dim);
@ -103,12 +121,98 @@ public:
}
}
virtual std::string className(void) const { return "moeoHypContinue"; }
private:
protected:
moeoArchive <MOEOT> & arch;
moeoHyperVolumeDifferenceMetric <ObjectiveVector> metric;
MetricT metric;
std::vector <ObjectiveVector> OptimSet;
};
/**
Continues until the (feasible or unfeasible) given Pareto set is reached.
@ingroup Continuators
*/
template< class MOEOT, class MetricT = moeoDualHyperVolumeDifferenceMetric<typename MOEOT::ObjectiveVector> >
class moeoDualHypContinue: public moeoHypContinue<MOEOT, MetricT >
{
protected:
bool is_feasible;
using moeoHypContinue<MOEOT, MetricT>::arch;
using moeoHypContinue<MOEOT, MetricT>::OptimSet;
public:
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
typedef typename ObjectiveVector::Type AtomType;
/** A continuator that stops once a given Pareto front has been reached
*
* You should specify the feasibility of the targeted front.
* NOTE: the MOEOT::ObjectiveVector is supposed to implement the moeoDualRealObjectiveVector interface.
*
*/
moeoDualHypContinue<MOEOT, MetricT>( const std::vector<AtomType> & _OptimVec, bool _is_feasible, moeoArchive < MOEOT > & _archive, bool _normalize=true, double _rho=1.1 )
: moeoHypContinue<MOEOT, MetricT>( _OptimVec, _archive, _normalize, _rho ), is_feasible(_is_feasible)
{
assert( _OptimVec.size() > 0);
vectorToParetoSet(_OptimVec);
}
/** A continuator that stops once a given Pareto front has been reached
*
* You should specify the feasibility of the targeted front.
* NOTE: the MOEOT::ObjectiveVector is supposed to implement the moeoDualRealObjectiveVector interface.
*
*/
moeoDualHypContinue<MOEOT, MetricT>( const std::vector<AtomType> & _OptimVec, bool _is_feasible, moeoArchive < MOEOT > & _archive, bool _normalize=true, ObjectiveVector& _ref_point=NULL )
: moeoHypContinue<MOEOT, MetricT>( _OptimVec, _archive, _normalize, _ref_point ), is_feasible(_is_feasible)
{
assert( _OptimVec.size() > 0);
vectorToParetoSet(_OptimVec);
}
/** Returns false when a ParetoSet is reached. */
virtual bool operator() ( const eoPop<MOEOT>& _pop )
{
std::vector<ObjectiveVector> bestCurrentParetoSet = pareto( arch );
#ifndef NDEBUG
assert( bestCurrentParetoSet.size() > 0 );
for( unsigned int i=1; i<bestCurrentParetoSet.size(); ++i ) {
assert( bestCurrentParetoSet[i].is_feasible() == bestCurrentParetoSet[0].is_feasible() );
}
#endif
// The current Pareto front is either feasible or unfeasible.
// It could not contains both kind of objective vectors, because a feasible solution always dominates an unfeasible front.
if( bestCurrentParetoSet[0].is_feasible() != OptimSet[0].is_feasible() ) {
return false;
}
return is_null_hypervolume( bestCurrentParetoSet );
}
protected:
using moeoHypContinue<MOEOT, MetricT>::pareto;
using moeoHypContinue<MOEOT, MetricT>::is_null_hypervolume;
/** Translate a vector given as param to the ParetoSet that should be reached. */
virtual void vectorToParetoSet(const std::vector<AtomType> & _OptimVec)
{
unsigned dim = (unsigned)(_OptimVec.size()/ObjectiveVector::Traits::nObjectives());
OptimSet.resize(dim);
unsigned k=0;
for(size_t i=0; i < dim; i++) {
for (size_t j=0; j < ObjectiveVector::Traits::nObjectives(); j++) {
// Use the feasibility declaration of an eoDualFitness
OptimSet[i][j] = AtomType(_OptimVec[k++], is_feasible);
}
}
}
};
#endif

View file

@ -0,0 +1,151 @@
/*
(c) 2010 Thales group
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; version 2
of the License.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: http://eodev.sourceforge.net
Authors:
Johann Dréo <johann.dreo@thalesgroup.com>
*/
#ifndef _DUALREALOBJECTIVEVECTOR_H_
#define _DUALREALOBJECTIVEVECTOR_H_
#include <iostream>
#include <math.h>
#include <eo>
#include <comparator/moeoObjectiveObjectiveVectorComparator.h>
#include <comparator/moeoParetoObjectiveVectorComparator.h>
#include <core/moeoScalarObjectiveVector.h>
template < class ObjectiveVectorTraits, class T = eoMaximizingDualFitness /* can be an eoMinimizingDualFitness */>
class moeoDualRealObjectiveVector : public moeoScalarObjectiveVector<ObjectiveVectorTraits, T >
{
protected:
bool _is_feasible;
public:
using moeoScalarObjectiveVector < ObjectiveVectorTraits, T >::size;
using moeoScalarObjectiveVector < ObjectiveVectorTraits, T >::operator[];
moeoDualRealObjectiveVector(double value=0.0, bool feasible = false)
: moeoScalarObjectiveVector<ObjectiveVectorTraits,T>
( T(value, feasible) ) {}
bool is_feasible() const
{
#ifndef NDEBUG
// if the feasibility is correctly assigned,
// every scalar's feasibility should be equal to the objective vector
for( typename moeoDualRealObjectiveVector::const_iterator it = this->begin(), end = this->end(); it != end; ++it ) {
assert( it->is_feasible() == _is_feasible );
}
#endif
return _is_feasible;
}
//! One should ensure that feasabilities of scalars are all the same
void is_feasible( bool value )
{
#ifndef NDEBUG
for( typename moeoDualRealObjectiveVector::const_iterator it = this->begin(), end = this->end(); it != end; ++it ) {
assert( it->is_feasible() == value );
}
#endif
_is_feasible = value;
}
bool dominates(const moeoRealObjectiveVector < ObjectiveVectorTraits > & other) const
{
// am I better than the other ?
// if I'm feasible and the other is not
if( this->is_feasible() && !other.is_feasible() ) {
// no, the other has a better objective
return true;
} else if( !this->is_feasible() && other.is_feasible() ) {
// yes, a feasible objective is always better than an unfeasible one
return false;
} else {
// the two objective are of the same type
// lets rely on the comparator
moeoParetoObjectiveVectorComparator< moeoDualRealObjectiveVector<ObjectiveVectorTraits> > comparator;
return comparator(other, *this);
}
}
//! Use when maximizing an
bool operator<(const moeoDualRealObjectiveVector < ObjectiveVectorTraits > & other) const
{
// am I better than the other ?
// if I'm feasible and the other is not
if( this->is_feasible() && !other.is_feasible() ) {
// no, the other has a better objective
return true;
} else if( !this->is_feasible() && other.is_feasible() ) {
// yes, a feasible objective is always better than an unfeasible one
return false;
} else {
moeoObjectiveObjectiveVectorComparator < moeoDualRealObjectiveVector < ObjectiveVectorTraits > > cmp;
return cmp(*this, other);
}
}
};
/**
* Output for a moeoDualRealObjectiveVector object
* @param _os output stream
* @param _objectiveVector the objective vector to write
*/
template<class ObjectiveVectorTraits, class T>
std::ostream & operator<<( std::ostream & _os, const moeoDualRealObjectiveVector<ObjectiveVectorTraits,T> & _objectiveVector )
{
for( unsigned int i=0; i<_objectiveVector.size()-1; i++ ) {
_os << _objectiveVector[i] << " ";
}
_os << _objectiveVector[_objectiveVector.size()-1];
return _os;
}
/**
* Input for a moeoDualRealObjectiveVector object
* @param _is input stream
* @param _objectiveVector the objective vector to read
*/
template<class ObjectiveVectorTraits, class T>
std::istream & operator>>( std::istream & _is, moeoDualRealObjectiveVector<ObjectiveVectorTraits,T> & _objectiveVector )
{
_objectiveVector = moeoDualRealObjectiveVector<ObjectiveVectorTraits,T> ();
for( unsigned int i=0; i<_objectiveVector.size(); i++ ) {
_is >> _objectiveVector[i];
}
return _is;
}
#endif /*_DUALREALOBJECTIVEVECTOR_H_*/

View file

@ -0,0 +1,179 @@
/*
(c) 2010 Thales group
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; version 2
of the License.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: http://eodev.sourceforge.net
Authors:
Johann Dréo <johann.dreo@thalesgroup.com>
*/
#ifndef MOEOSCALAROBJECTIVEVECTOR_H_
#define MOEOSCALAROBJECTIVEVECTOR_H_
#include <iostream>
#include <math.h>
#include <comparator/moeoObjectiveObjectiveVectorComparator.h>
#include <comparator/moeoParetoObjectiveVectorComparator.h>
#include <core/moeoObjectiveVector.h>
/**
* This class allows to represent a solution in the objective space (phenotypic representation) by a std::vector of typed values,
* i.e. that an objective value is represented using a T, and this for any objective.
*/
template < class ObjectiveVectorTraits, class T >
class moeoScalarObjectiveVector : public moeoObjectiveVector < ObjectiveVectorTraits, T >
{
public:
using moeoObjectiveVector < ObjectiveVectorTraits, T >::size;
using moeoObjectiveVector < ObjectiveVectorTraits, T >::operator[];
/**
* Ctor
*/
moeoScalarObjectiveVector(T _value = 0.0) : moeoObjectiveVector < ObjectiveVectorTraits, T > (_value)
{}
/**
* Ctor from a vector of Ts
* @param _v the std::vector < T >
*/
moeoScalarObjectiveVector(std::vector < T > & _v) : moeoObjectiveVector < ObjectiveVectorTraits, T > (_v)
{}
/**
* Returns true if the current objective vector dominates _other according to the Pareto dominance relation
* (but it's better to use a moeoObjectiveVectorComparator object to compare solutions)
* @param _other the other moeoScalarObjectiveVector object to compare with
*/
bool dominates(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const
{
moeoParetoObjectiveVectorComparator < moeoScalarObjectiveVector<ObjectiveVectorTraits, T> > 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 moeoScalarObjectiveVector object to compare with
*/
bool operator==(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const
{
for (unsigned int i=0; i < size(); i++)
{
if ( fabs(operator[](i) - _other[i]) > 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 moeoScalarObjectiveVector object to compare with
*/
bool operator!=(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const
{
return ! operator==(_other);
}
/**
* Returns true if the current objective vector is smaller than _other on the first objective, then on the second, and so on
* (can be usefull for sorting/printing)
* @param _other the other moeoScalarObjectiveVector object to compare with
*/
bool operator<(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const
{
moeoObjectiveObjectiveVectorComparator < moeoScalarObjectiveVector < ObjectiveVectorTraits, T > > cmp;
return cmp(*this, _other);
}
/**
* Returns true if the current objective vector is greater than _other on the first objective, then on the second, and so on
* (can be usefull for sorting/printing)
* @param _other the other moeoScalarObjectiveVector object to compare with
*/
bool operator>(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const
{
return _other < *this;
}
/**
* Returns true if the current objective vector is smaller than or equal to _other on the first objective, then on the second, and so on
* (can be usefull for sorting/printing)
* @param _other the other moeoScalarObjectiveVector object to compare with
*/
bool operator<=(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const
{
return operator==(_other) || operator<(_other);
}
/**
* Returns true if the current objective vector is greater than or equal to _other on the first objective, then on the second, and so on
* (can be usefull for sorting/printing)
* @param _other the other moeoScalarObjectiveVector object to compare with
*/
bool operator>=(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const
{
return operator==(_other) || operator>(_other);
}
};
/**
* Output for a moeoScalarObjectiveVector object
* @param _os output stream
* @param _objectiveVector the objective vector to write
*/
template < class ObjectiveVectorTraits, class T >
std::ostream & operator<<(std::ostream & _os, const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _objectiveVector)
{
for (unsigned int i=0; i<_objectiveVector.size()-1; i++)
_os << _objectiveVector[i] << " ";
_os << _objectiveVector[_objectiveVector.size()-1];
return _os;
}
/**
* Input for a moeoScalarObjectiveVector object
* @param _is input stream
* @param _objectiveVector the objective vector to read
*/
template < class ObjectiveVectorTraits, class T >
std::istream & operator>>(std::istream & _is, moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _objectiveVector)
{
_objectiveVector = moeoScalarObjectiveVector < ObjectiveVectorTraits, T > ();
for (unsigned int i=0; i<_objectiveVector.size(); i++)
{
_is >> _objectiveVector[i];
}
return _is;
}
#endif /*MOEOSCALAROBJECTIVEVECTOR_H_*/

View file

@ -1,38 +1,38 @@
/*
* <moeoDominanceDepthFitnessAssignment.h>
* Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2008
* (C) OPAC Team, LIFL, 2002-2008
*
* Arnaud Liefooghe
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*
* ParadisEO WebSite : http://paradiseo.gforge.inria.fr
* Contact: paradiseo-help@lists.gforge.inria.fr
*
*/
* <moeoDominanceDepthFitnessAssignment.h>
* Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2008
* (C) OPAC Team, LIFL, 2002-2008
*
* Arnaud Liefooghe
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*
* ParadisEO WebSite : http://paradiseo.gforge.inria.fr
* Contact: paradiseo-help@lists.gforge.inria.fr
*
*/
//-----------------------------------------------------------------------------
#ifndef MOEODOMINANCEDEPTHFITNESSASSIGNMENT_H_
@ -44,7 +44,7 @@
#include <comparator/moeoObjectiveVectorComparator.h>
#include <comparator/moeoParetoObjectiveVectorComparator.h>
#include <fitness/moeoDominanceBasedFitnessAssignment.h>
#include <comparator/moeoPtrComparator.h>
/**
* Fitness assignment sheme based on Pareto-dominance count proposed in:
@ -55,69 +55,69 @@
*/
template < class MOEOT >
class moeoDominanceDepthFitnessAssignment : public moeoDominanceBasedFitnessAssignment < MOEOT >
{
public:
{
public:
/** the objective vector type of the solutions */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Default ctor
*/
moeoDominanceDepthFitnessAssignment() : comparator(paretoComparator)
moeoDominanceDepthFitnessAssignment(bool _rm_equiv_flag_in_2D = false) : comparator(paretoComparator), rm_equiv_flag_in_2D(_rm_equiv_flag_in_2D)
{}
/**
* Ctor where you can choose your own way to compare objective vectors
* @param _comparator the functor used to compare objective vectors
*/
moeoDominanceDepthFitnessAssignment(moeoObjectiveVectorComparator < ObjectiveVector > & _comparator) : comparator(_comparator)
moeoDominanceDepthFitnessAssignment(moeoObjectiveVectorComparator < ObjectiveVector > & _comparator, bool _rm_equiv_flag_in_2D = true) : comparator(_comparator), rm_equiv_flag_in_2D(_rm_equiv_flag_in_2D)
{}
/**
* Sets the fitness values for every solution contained in the population _pop
* @param _pop the population
*/
void operator()(eoPop < MOEOT > & _pop)
{
// number of objectives for the problem under consideration
unsigned int nObjectives = MOEOT::ObjectiveVector::nObjectives();
if (nObjectives == 1)
// number of objectives for the problem under consideration
unsigned int nObjectives = MOEOT::ObjectiveVector::nObjectives();
if (nObjectives == 1)
{
// one objective
oneObjective(_pop);
// one objective
oneObjective(_pop);
}
else if (nObjectives == 2)
else if (nObjectives == 2)
{
// two objectives (the two objectives function is still to implement)
mObjectives(_pop);
// two objectives
twoObjectives(_pop);
}
else if (nObjectives > 2)
else if (nObjectives > 2)
{
// more than two objectives
mObjectives(_pop);
// more than two objectives
mObjectives(_pop);
}
else
else
{
// problem with the number of objectives
throw std::runtime_error("Problem with the number of objectives in moeoDominanceDepthFitnessAssignment");
// problem with the number of objectives
throw std::runtime_error("Problem with the number of objectives in moeoDominanceDepthFitnessAssignment");
}
// a higher fitness is better, so the values need to be inverted
double max = _pop[0].fitness();
for (unsigned int i=1 ; i<_pop.size() ; i++)
// a higher fitness is better, so the values need to be inverted
double max = _pop[0].fitness();
for (unsigned int i=1 ; i<_pop.size() ; i++)
{
max = std::max(max, _pop[i].fitness());
max = std::max(max, _pop[i].fitness());
}
for (unsigned int i=0 ; i<_pop.size() ; i++)
for (unsigned int i=0 ; i<_pop.size() ; i++)
{
_pop[i].fitness(max - _pop[i].fitness());
_pop[i].fitness(max - _pop[i].fitness());
}
}
/**
* Updates the fitness values of the whole population _pop by taking the deletion of the objective vector _objVec into account.
* @param _pop the population
@ -125,141 +125,209 @@ class moeoDominanceDepthFitnessAssignment : public moeoDominanceBasedFitnessAssi
*/
void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec)
{
for (unsigned int i=0; i<_pop.size(); i++)
for (unsigned int i=0; i<_pop.size(); i++)
{
// if _pop[i] is dominated by _objVec
if ( comparator(_pop[i].objectiveVector(), _objVec) )
// if _pop[i] is dominated by _objVec
if ( comparator(_pop[i].objectiveVector(), _objVec) )
{
_pop[i].fitness(_pop[i].fitness()+1);
_pop[i].fitness(_pop[i].fitness()+1);
}
}
}
private:
private:
/** Functor to compare two objective vectors */
moeoObjectiveVectorComparator < ObjectiveVector > & comparator;
/** Functor to compare two objective vectors according to Pareto dominance relation */
moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator;
/** flag to remove equivament solutions */
bool rm_equiv_flag_in_2D;
/** Functor allowing to compare two solutions according to their first objective value, then their second, and so on. */
class ObjectiveComparator : public moeoComparator < MOEOT >
{
public:
class ObjectiveComparator : public moeoComparator < MOEOT >
{
public:
/**
* Returns true if _moeo1 < _moeo2 on the first objective, then on the second, and so on
* Returns true if _moeo1 > _moeo2 on the first objective, then on the second, and so on
* @param _moeo1 the first solution
* @param _moeo2 the second solution
*/
bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
{
return cmp(_moeo1.objectiveVector(), _moeo2.objectiveVector());
return cmp(_moeo2.objectiveVector(), _moeo1.objectiveVector());
}
private:
private:
/** the corresponding comparator for objective vectors */
moeoObjectiveObjectiveVectorComparator < ObjectiveVector > cmp;
}
}
objComparator;
/**
* Sets the fitness values for mono-objective problems
* @param _pop the population
*/
void oneObjective (eoPop < MOEOT > & _pop)
{
// sorts the population in the ascending order
std::sort(_pop.begin(), _pop.end(), objComparator);
// assign fitness values
unsigned int rank = 1;
_pop[_pop.size()-1].fitness(rank);
for (int i=_pop.size()-2; i>=0; i--)
// sorts the population in the ascending order
std::sort(_pop.begin(), _pop.end(), objComparator);
// assign fitness values
unsigned int rank = 1;
_pop[0].fitness(rank);
for (unsigned int i=1; i<_pop.size(); i++)
{
if (_pop[i].objectiveVector() != _pop[i+1].objectiveVector())
if (_pop[i].objectiveVector() != _pop[i-1].objectiveVector())
{
rank++;
rank++;
}
_pop[i].fitness(rank);
_pop[i].fitness(rank);
}
}
/**
* Sets the fitness values for bi-objective problems with a complexity of O(n log n), where n stands for the population size
* @param _pop the population
*/
void twoObjectives (eoPop < MOEOT > & _pop)
{
//... TO DO !
double value_obj1;
unsigned int front;
unsigned int last_front = 0;
bool equiv_flag;
// sort pointers to pop's individuals with respect to the first objective (0) in the reverse order
std::vector<MOEOT *> sortedptrpop;
sortedptrpop.resize(_pop.size());
for(unsigned int i=0; i<_pop.size(); i++)
{
sortedptrpop[i] = & (_pop[i]);
}
moeoPtrComparator<MOEOT> cmp(objComparator);
std::sort(sortedptrpop.begin(), sortedptrpop.end(), cmp);
// compute an upper bound on the second objective (1)
double max_obj1 = std::numeric_limits<double>::min();
for(unsigned int i=0; i<_pop.size(); i++)
{
max_obj1 = std::max(max_obj1, _pop[i].objectiveVector()[1]);
}
max_obj1 += 1.0;
// initialize a vector with the max_obj1 value everywhere
std::vector<double> d(_pop.size(), max_obj1);
// initialize fronts
std::vector<std::vector<unsigned int> > fronts(_pop.size());
// compute rank for each individual
for(unsigned int i=0; i<sortedptrpop.size(); i++)
{
equiv_flag = false;
// check for equivalent solutions and assign them to the worst front
if (i>0)
{
if ( (rm_equiv_flag_in_2D) && (sortedptrpop[i]->objectiveVector() == sortedptrpop[i-1]->objectiveVector()) )
{
equiv_flag = true;
fronts.back().push_back(i);
}
}
if (!equiv_flag)
{
// the value of the second objective for the current solutions
value_obj1 = sortedptrpop[i]->objectiveVector()[1];
// if we maximize, take the opposite value
if (MOEOT::ObjectiveVector::maximizing(1))
value_obj1 = max_obj1 - value_obj1;
// perform binary search (log n)
std::vector<double>::iterator it = std::upper_bound(d.begin(), d.begin() + last_front, value_obj1);
// retrieve the corresponding front
front = (unsigned int)(it - d.begin());
if (front == last_front)
last_front++;
// update
*it = value_obj1;
// add the solution to the corresponding front
fronts[front].push_back(i);
}
}
// assign the fitness value (rank) to each individual
for (unsigned int i=0; i<fronts.size(); i++)
{
for (unsigned int j=0; j<fronts[i].size(); j++)
{
sortedptrpop[fronts[i][j]]->fitness(i+1);
}
}
}
/**
* Sets the fitness values for problems with more than two objectives with a complexity of O(n² log n), where n stands for the population size
* @param _pop the population
*/
void mObjectives (eoPop < MOEOT > & _pop)
{
// S[i] = indexes of the individuals dominated by _pop[i]
std::vector < std::vector<unsigned int> > S(_pop.size());
// n[i] = number of individuals that dominate the individual _pop[i]
std::vector < unsigned int > n(_pop.size(), 0);
// fronts: F[i] = indexes of the individuals contained in the ith front
std::vector < std::vector<unsigned int> > F(_pop.size()+2);
// used to store the number of the first front
F[1].reserve(_pop.size());
for (unsigned int p=0; p<_pop.size(); p++)
// S[i] = indexes of the individuals dominated by _pop[i]
std::vector < std::vector<unsigned int> > S(_pop.size());
// n[i] = number of individuals that dominate the individual _pop[i]
std::vector < unsigned int > n(_pop.size(), 0);
// fronts: F[i] = indexes of the individuals contained in the ith front
std::vector < std::vector<unsigned int> > F(_pop.size()+2);
// used to store the number of the first front
F[1].reserve(_pop.size());
for (unsigned int p=0; p<_pop.size(); p++)
{
for (unsigned int q=0; q<_pop.size(); q++)
for (unsigned int q=0; q<_pop.size(); q++)
{
// if q is dominated by p
if ( comparator(_pop[q].objectiveVector(), _pop[p].objectiveVector()) )
// if q is dominated by p
if ( comparator(_pop[q].objectiveVector(), _pop[p].objectiveVector()) )
{
// add q to the set of solutions dominated by p
S[p].push_back(q);
// add q to the set of solutions dominated by p
S[p].push_back(q);
}
// if p is dominated by q
else if ( comparator(_pop[p].objectiveVector(), _pop[q].objectiveVector()) )
// if p is dominated by q
else if ( comparator(_pop[p].objectiveVector(), _pop[q].objectiveVector()) )
{
// increment the domination counter of p
n[p]++;
// increment the domination counter of p
n[p]++;
}
}
// if no individual dominates p
if (n[p] == 0)
// if no individual dominates p
if (n[p] == 0)
{
// p belongs to the first front
_pop[p].fitness(1);
F[1].push_back(p);
// p belongs to the first front
_pop[p].fitness(1);
F[1].push_back(p);
}
}
// front counter
unsigned int counter=1;
unsigned int p,q;
while (! F[counter].empty())
// front counter
unsigned int counter=1;
unsigned int p,q;
while (! F[counter].empty())
{
// used to store the number of the next front
F[counter+1].reserve(_pop.size());
for (unsigned int i=0; i<F[counter].size(); i++)
// used to store the number of the next front
F[counter+1].reserve(_pop.size());
for (unsigned int i=0; i<F[counter].size(); i++)
{
p = F[counter][i];
for (unsigned int j=0; j<S[p].size(); j++)
p = F[counter][i];
for (unsigned int j=0; j<S[p].size(); j++)
{
q = S[p][j];
n[q]--;
// if no individual dominates q anymore
if (n[q] == 0)
q = S[p][j];
n[q]--;
// if no individual dominates q anymore
if (n[q] == 0)
{
// q belongs to the next front
_pop[q].fitness(counter+1);
F[counter+1].push_back(q);
// q belongs to the next front
_pop[q].fitness(counter+1);
F[counter+1].push_back(q);
}
}
}
counter++;
counter++;
}
}
} ;
} ;
#endif /*MOEODOMINANCEDEPTHFITNESSASSIGNMENT_H_*/

View file

@ -0,0 +1,92 @@
#include <fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h>
template<class MOEOT>
class moeoExpBinaryIndicatorBasedDualFitnessAssignment : public moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>
{
protected:
eoPop<MOEOT> _feasible_pop;
eoPop<MOEOT> _unfeasible_pop;
public:
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
typedef typename ObjectiveVector::Type Type;
using moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>::values;
moeoExpBinaryIndicatorBasedDualFitnessAssignment(
moeoNormalizedSolutionVsSolutionBinaryMetric<ObjectiveVector,double> & metric,
const double kappa = 0.05
) : moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>( metric, kappa ) {}
//! Split up the population in two: in one pop the feasible individual, in the other the feasible ones
virtual void split( eoPop<MOEOT> & pop )
{
_feasible_pop.reserve(pop.size());
_unfeasible_pop.reserve(pop.size());
for( typename eoPop<MOEOT>::iterator it=pop.begin(), end=pop.end(); it != end; ++it ) {
// The ObjectiveVector should implement "is_feasible"
if( it->objectiveVector().is_feasible() ) {
_feasible_pop.push_back( *it );
} else {
_unfeasible_pop.push_back( *it );
}
}
}
/*! If the population is homogeneous (only composed of feasible individuals or unfeasible ones),
* then apply the operators on the whole population.
* But, if there is at least one feasible individual, then apply them only on the feasible individuals.
*/
virtual void operator()(eoPop < MOEOT > & pop)
{
// separate the pop in the members
split( pop );
eoPop<MOEOT>* ppop;
// if there is at least one feasible individual, it will supersede all the unfeasible ones
if( _feasible_pop.size() == 0 ) {
ppop = & _unfeasible_pop;
} else {
ppop = & _feasible_pop;
}
this->setup(*ppop);
this->computeValues(*ppop);
this->setFitnesses(*ppop);
}
/**
* Compute every indicator value in values (values[i] = I(_v[i], _o))
* @param _pop the population
*/
void computeValues(const eoPop < MOEOT > & _pop)
{
values.clear();
values.resize(_pop.size());
for (unsigned int i=0; i<_pop.size(); i++)
{
values[i].resize(_pop.size());
// the metric may not be symetric, thus neither is the matrix
for (unsigned int j=0; j<_pop.size(); j++)
{
if (i != j)
{
values[i][j] = Type( metric(_pop[i].objectiveVector(), _pop[j].objectiveVector()), _pop[i].objectiveVector().is_feasible() );
}
}
}
}
virtual void setFitnesses(eoPop < MOEOT > & pop)
{
for (unsigned int i=0; i<pop.size(); i++) {
// We should maintain the feasibility of the fitness across computations
pop[i].fitness( this->computeFitness(i), pop[i].fitness().is_feasible() );
}
}
};

View file

@ -58,6 +58,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB
/** The type of objective vector */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
typedef typename ObjectiveVector::Type Type;
/**
* Ctor.
@ -72,7 +73,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB
* Sets the fitness values for every solution contained in the population _pop
* @param _pop the population
*/
void operator()(eoPop < MOEOT > & _pop)
virtual void operator()(eoPop < MOEOT > & _pop)
{
// 1 - setting of the bounds
setup(_pop);
@ -145,7 +146,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB
/** the scaling factor */
double kappa;
/** the computed indicator values */
std::vector < std::vector<double> > values;
std::vector < std::vector<Type> > values;
/**
@ -154,7 +155,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB
*/
void setup(const eoPop < MOEOT > & _pop)
{
double min, max;
typename MOEOT::ObjectiveVector::Type min, max;
for (unsigned int i=0; i<ObjectiveVector::Traits::nObjectives(); i++)
{
min = _pop[0].objectiveVector()[i];
@ -181,11 +182,12 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB
for (unsigned int i=0; i<_pop.size(); i++)
{
values[i].resize(_pop.size());
// the metric may not be symetric, thus neither is the matrix
for (unsigned int j=0; j<_pop.size(); j++)
{
if (i != j)
{
values[i][j] = metric(_pop[i].objectiveVector(), _pop[j].objectiveVector());
values[i][j] = Type( metric(_pop[i].objectiveVector(), _pop[j].objectiveVector()) );
}
}
}
@ -193,10 +195,10 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB
/**
* Sets the fitness value of the whple population
* Sets the fitness value of the whole population
* @param _pop the population
*/
void setFitnesses(eoPop < MOEOT > & _pop)
virtual void setFitnesses(eoPop < MOEOT > & _pop)
{
for (unsigned int i=0; i<_pop.size(); i++)
{
@ -209,9 +211,9 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB
* Returns the fitness value of the _idx th individual of the population
* @param _idx the index
*/
double computeFitness(const unsigned int _idx)
Type computeFitness(const unsigned int _idx)
{
double result = 0;
Type result(0.0);
for (unsigned int i=0; i<values.size(); i++)
{
if (i != _idx)

View file

@ -56,7 +56,7 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric <
* @param _normalize allow to normalize data (default true)
* @param _rho coefficient to determine the reference point.
*/
moeoHyperVolumeDifferenceMetric(bool _normalize=true, double _rho=1.1): normalize(_normalize), rho(_rho), ref_point(NULL){
moeoHyperVolumeDifferenceMetric(bool _normalize=true, double _rho=1.1): normalize(_normalize), rho(_rho), ref_point(/*NULL*/){
bounds.resize(ObjectiveVector::Traits::nObjectives());
// initialize bounds in case someone does not want to use them
for (unsigned int i=0; i<ObjectiveVector::Traits::nObjectives(); i++)
@ -70,7 +70,7 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric <
* @param _normalize allow to normalize data (default true)
* @param _ref_point the reference point
*/
moeoHyperVolumeDifferenceMetric(bool _normalize=true, ObjectiveVector& _ref_point=NULL): normalize(_normalize), rho(0.0), ref_point(_ref_point){
moeoHyperVolumeDifferenceMetric(bool _normalize/*=true*/, ObjectiveVector& _ref_point/*=NULL*/): normalize(_normalize), rho(0.0), ref_point(_ref_point){
bounds.resize(ObjectiveVector::Traits::nObjectives());
// initialize bounds in case someone does not want to use them
for (unsigned int i=0; i<ObjectiveVector::Traits::nObjectives(); i++)
@ -86,41 +86,42 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric <
*/
double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2)
{
double hypervolume_set1;
double hypervolume_set2;
if(rho >= 1.0){
//determine bounds
setup(_set1, _set2);
//determine reference point
for (unsigned int i=0; i<ObjectiveVector::Traits::nObjectives(); i++){
if(normalize){
if (ObjectiveVector::Traits::minimizing(i))
ref_point[i]= rho;
else
ref_point[i]= 1-rho;
}
else{
if (ObjectiveVector::Traits::minimizing(i))
ref_point[i]= bounds[i].maximum() * rho;
else
ref_point[i]= bounds[i].maximum() * (1-rho);
}
}
//if no normalization, reinit bounds to O..1 for
if(!normalize)
for (unsigned int i=0; i<ObjectiveVector::Traits::nObjectives(); i++)
bounds[i] = eoRealInterval(0,1);
double hypervolume_set1;
double hypervolume_set2;
}
else if(normalize)
setup(_set1, _set2);
if(rho >= 1.0){
//determine bounds
setup(_set1, _set2);
//determine reference point
for (unsigned int i=0; i<ObjectiveVector::Traits::nObjectives(); i++){
if(normalize){
if (ObjectiveVector::Traits::minimizing(i))
ref_point[i]= rho;
else
ref_point[i]= 1-rho;
}
else{
if (ObjectiveVector::Traits::minimizing(i))
ref_point[i]= bounds[i].maximum() * rho;
else
ref_point[i]= bounds[i].maximum() * (1-rho);
}
}
//if no normalization, reinit bounds to O..1 for
if(!normalize)
for (unsigned int i=0; i<ObjectiveVector::Traits::nObjectives(); i++)
bounds[i] = eoRealInterval(0,1);
moeoHyperVolumeMetric <ObjectiveVector> unaryMetric(ref_point, bounds);
hypervolume_set1 = unaryMetric(_set1);
hypervolume_set2 = unaryMetric(_set2);
}
else if(normalize)
setup(_set1, _set2);
return hypervolume_set1 - hypervolume_set2;
moeoHyperVolumeMetric <ObjectiveVector> unaryMetric(ref_point, bounds);
hypervolume_set1 = unaryMetric(_set1);
hypervolume_set2 = unaryMetric(_set2);
return hypervolume_set1 - hypervolume_set2;
}
/**
@ -132,7 +133,7 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric <
}
/**
* method caclulate bounds for the normalization
* method calculate bounds for the normalization
* @param _set1 the vector contains all objective Vector of the first pareto front
* @param _set2 the vector contains all objective Vector of the second pareto front
*/
@ -149,7 +150,7 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric <
}
#endif
double min, max;
typename ObjectiveVector::Type min, max;
unsigned int nbObj=ObjectiveVector::Traits::nObjectives();
bounds.resize(nbObj);
for (unsigned int i=0; i<nbObj; i++){
@ -163,12 +164,26 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric <
min = std::min(min, _set2[j][i]);
max = std::max(max, _set2[j][i]);
}
bounds[i] = eoRealInterval(min, max);
if( min == max ) {
bounds[i] = eoRealInterval(min-tiny(), max+tiny());
} else {
bounds[i] = eoRealInterval(min, max);
}
}
}
}
private:
protected:
/**
* Returns a very small value that can be used to avoid extreme cases (where the min bound == the max bound)
*/
static double tiny()
{
return 1e-6;
}
protected:
/*boolean indicates if data must be normalized or not*/
bool normalize;
@ -182,4 +197,90 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric <
};
template<class ObjectiveVector>
class moeoDualHyperVolumeDifferenceMetric : public moeoHyperVolumeDifferenceMetric<ObjectiveVector>
{
protected:
using moeoHyperVolumeDifferenceMetric<ObjectiveVector>::rho;
using moeoHyperVolumeDifferenceMetric<ObjectiveVector>::normalize;
using moeoHyperVolumeDifferenceMetric<ObjectiveVector>::ref_point;
using moeoHyperVolumeDifferenceMetric<ObjectiveVector>::bounds;
public:
typedef typename ObjectiveVector::Type Type;
moeoDualHyperVolumeDifferenceMetric( bool _normalize=true, double _rho=1.1)
: moeoHyperVolumeDifferenceMetric<ObjectiveVector>(_normalize, _rho)
{
}
moeoDualHyperVolumeDifferenceMetric( bool _normalize/*=true*/, ObjectiveVector& _ref_point/*=NULL*/ )
: moeoHyperVolumeDifferenceMetric<ObjectiveVector>( _normalize, _ref_point )
{
}
/**
* calculates and returns the HyperVolume value of a pareto front
* @param _set1 the vector contains all objective Vector of the first pareto front
* @param _set2 the vector contains all objective Vector of the second pareto front
*/
double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2)
{
#ifndef NDEBUG
// the two sets must be homogeneous in feasibility
assert( _set1.size() > 0 );
for( unsigned int i=1; i<_set1.size(); ++i ) {
assert( _set1[i].is_feasible() == _set1[0].is_feasible() );
}
assert( _set2.size() > 0 );
for( unsigned int i=1; i<_set2.size(); ++i ) {
assert( _set2[i].is_feasible() == _set2[0].is_feasible() );
}
// and they must have the same feasibility
assert( _set1[0].is_feasible() == _set2[0].is_feasible() );
#endif
bool feasible = _set1[0].is_feasible();
double hypervolume_set1;
double hypervolume_set2;
if(rho >= 1.0){
//determine bounds
setup(_set1, _set2);
//determine reference point
for (unsigned int i=0; i<ObjectiveVector::Traits::nObjectives(); i++){
if(normalize){
if (ObjectiveVector::Traits::minimizing(i))
ref_point[i]= Type(rho, feasible);
else
ref_point[i]= Type(1-rho, feasible);
}
else{
if (ObjectiveVector::Traits::minimizing(i))
ref_point[i]= Type(bounds[i].maximum() * rho, feasible);
else
ref_point[i]= Type(bounds[i].maximum() * (1-rho), feasible);
}
}
//if no normalization, reinit bounds to O..1 for
if(!normalize)
for (unsigned int i=0; i<ObjectiveVector::Traits::nObjectives(); i++)
bounds[i] = eoRealInterval(0,1);
}
else if(normalize)
setup(_set1, _set2);
moeoHyperVolumeMetric <ObjectiveVector> unaryMetric(ref_point, bounds);
hypervolume_set1 = unaryMetric(_set1);
hypervolume_set2 = unaryMetric(_set2);
return hypervolume_set1 - hypervolume_set2;
}
};
#endif /*MOEOHYPERVOLUMEMETRIC_H_*/

View file

@ -152,7 +152,7 @@ class moeoHyperVolumeMetric : public moeoVectorUnaryMetric < ObjectiveVector , d
if(_set.size() < 1)
throw("Error in moeoHyperVolumeUnaryMetric::setup -> argument1: vector<ObjectiveVector> size must be greater than 0");
else{
double min, max;
typename ObjectiveVector::Type min, max;
unsigned int nbObj=ObjectiveVector::Traits::nObjectives();
bounds.resize(nbObj);
for (unsigned int i=0; i<nbObj; i++){

View file

@ -52,6 +52,8 @@ class moeoNormalizedSolutionVsSolutionBinaryMetric : public moeoSolutionVsSoluti
{
public:
typedef typename ObjectiveVector::Type Type;
/**
* Default ctr for any moeoNormalizedSolutionVsSolutionBinaryMetric object
*/
@ -72,7 +74,7 @@ class moeoNormalizedSolutionVsSolutionBinaryMetric : public moeoSolutionVsSoluti
* @param _max upper bound
* @param _obj the objective index
*/
void setup(double _min, double _max, unsigned int _obj)
void setup( Type _min, Type _max, unsigned int _obj)
{
if (_min == _max)
{

View file

@ -109,7 +109,7 @@ public:
* @param _set2 the second vector of objective vectors
*/
void setup(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2){
double min, max;
typename ObjectiveVector::Type min, max;
unsigned int nbObj=ObjectiveVector::Traits::nObjectives();
bounds.resize(nbObj);
for (unsigned int i=0; i<nbObj; i++){

View file

@ -88,7 +88,9 @@
#include <core/moeoIntVector.h>
#include <core/moeoObjectiveVector.h>
#include <core/moeoObjectiveVectorTraits.h>
#include <core/moeoScalarObjectiveVector.h>
#include <core/moeoRealObjectiveVector.h>
#include <core/moeoDualRealObjectiveVector.h>
#include <core/moeoRealVector.h>
#include <core/moeoVector.h>
@ -125,6 +127,7 @@
#include <fitness/moeoDominanceRankFitnessAssignment.h>
#include <fitness/moeoDummyFitnessAssignment.h>
#include <fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h>
#include <fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h>
#include <fitness/moeoFitnessAssignment.h>
#include <fitness/moeoIndicatorBasedFitnessAssignment.h>
#include <fitness/moeoReferencePointIndicatorBasedFitnessAssignment.h>

View file

@ -132,7 +132,7 @@ public:
*/
virtual void receive(void);
AIsland<bEOT> clone() const;
//AIsland<bEOT> clone() const;
protected: