diff --git a/archive_current.sh b/archive_current.sh index d43952087..3ba2d2bc2 100755 --- a/archive_current.sh +++ b/archive_current.sh @@ -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 diff --git a/cmake/Config.cmake b/cmake/Config.cmake index 8b08ff1c0..02593bac3 100644 --- a/cmake/Config.cmake +++ b/cmake/Config.cmake @@ -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) diff --git a/eo/src/eoDualFitness.h b/eo/src/eoDualFitness.h index 674fe075c..59d6f6d05 100644 --- a/eo/src/eoDualFitness.h +++ b/eo/src/eoDualFitness.h @@ -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 + 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 > 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& v) + eoDualFitness& operator=( const std::pair& 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 - eoDualFitness & operator=(const eoDualFitness& other ) + eoDualFitness & operator=( const eoDualFitness& other ) { if (this != &other) { this->_value = other._value; @@ -143,6 +156,17 @@ public: return *this; } + /* + //! Copy operator from a scalar + template + 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 - friend - eoDualFitness & operator+=( eoDualFitness & from, const eoDualFitness & that ) + template + eoDualFitness & operator+=( const T that ) { - from._value += that._value; + this->_value += that; + return *this; + } + + //! Add a given fitness to the current one + eoDualFitness & operator+=( const eoDualFitness & 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 - friend - eoDualFitness & operator-=( eoDualFitness & from, const eoDualFitness & that ) + template + eoDualFitness & operator-=( const T that ) { - from._value -= that._value; + this->_value -= that; + return *this; + } + + //! Substract a given fitness to the current one + eoDualFitness & operator-=( const eoDualFitness & 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 + eoDualFitness & operator/=( T that ) + { + this->_value /= that; + return *this; + } + + //! Add a given fitness to the current one + eoDualFitness & operator/=( const eoDualFitness & 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 + eoDualFitness 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 - eoDualFitness operator+(const eoDualFitness & that) + eoDualFitness operator+( const eoDualFitness & that ) { - eoDualFitness from( *this ); + eoDualFitness from( *this ); return from += that; } - // Add this fitness's value to that other, and return a _new_ instance with the result. - template - eoDualFitness operator-(const eoDualFitness & that) + template + eoDualFitness operator-( T that ) { - eoDualFitness from( *this ); + this->_value -= that; + return *this; + } + + // Add this fitness's value to that other, and return a _new_ instance with the result. + eoDualFitness operator-( const eoDualFitness & that ) + { + eoDualFitness from( *this ); return from -= that; } - //! Print an eoDualFitness instance as a pair of numbers, separated by a space - template - friend - std::ostream& operator<<(std::ostream& os, const eoDualFitness& f) + + template + eoDualFitness 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 operator/( const eoDualFitness & that ) + { + eoDualFitness 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 & fitness ) + { + os << fitness._value << " " << fitness._is_feasible; return os; } //! Read an eoDualFitness instance as a pair of numbers, separated by a space - template friend - std::istream& operator>>(std::istream& is, eoDualFitness& f) + std::istream& operator>>( std::istream& is, eoDualFitness & fitness ) { - F value; + BaseType value; is >> value; bool feasible; is >> feasible; - f = std::make_pair( value, feasible ); + fitness._value = value; + fitness._is_feasible = feasible; return is; } }; diff --git a/eo/src/serial/Utils.h b/eo/src/serial/Utils.h index b6ea360b3..5acc558ba 100644 --- a/eo/src/serial/Utils.h +++ b/eo/src/serial/Utils.h @@ -155,7 +155,7 @@ namespace eoserial inline void unpackBasePushBack( const Entity* obj, T& container ) { const Array* arr = static_cast( 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 & 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& 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 ) { diff --git a/eo/src/utils/eoRealBounds.h b/eo/src/utils/eoRealBounds.h index a41646d47..8d55d793a 100644 --- a/eo/src/utils/eoRealBounds.h +++ b/eo/src/utils/eoRealBounds.h @@ -27,9 +27,12 @@ #ifndef _eoRealBounds_h #define _eoRealBounds_h +#include #include #include // std::exceptions! + #include +#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 } diff --git a/moeo/src/algo/moeoIBEA.h b/moeo/src/algo/moeoIBEA.h index b0c1d0207..928e8f5a0 100644 --- a/moeo/src/algo/moeoIBEA.h +++ b/moeo/src/algo/moeoIBEA.h @@ -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(_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(_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(_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(_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(_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 */ diff --git a/moeo/src/continue/moeoHypContinue.h b/moeo/src/continue/moeoHypContinue.h index 4e656bf69..f6fbac34a 100644 --- a/moeo/src/continue/moeoHypContinue.h +++ b/moeo/src/continue/moeoHypContinue.h @@ -46,32 +46,45 @@ #include /** - 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 > class moeoHypContinue: public eoContinue { public: typedef typename MOEOT::ObjectiveVector ObjectiveVector; + typedef typename ObjectiveVector::Type AtomType; /// Ctor - moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, double _rho=1.1) + moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, double _rho=1.1) : eoContinue(), arch(_archive), metric(_normalize,_rho) { vectorToParetoSet(_OptimVec); } - moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, ObjectiveVector& _ref_point=NULL) + moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, ObjectiveVector& _ref_point=NULL) : eoContinue (), arch(_archive), metric(_normalize,_ref_point) { vectorToParetoSet(_OptimVec); } + /** Returns false when a ParetoSet is reached. */ virtual bool operator() ( const eoPop& _pop ) + { + std::vector bestCurrentParetoSet = pareto( arch ); + + return is_null_hypervolume( bestCurrentParetoSet ); + } + + virtual std::string className(void) const { return "moeoHypContinue"; } + +protected: + + std::vector pareto( moeoArchive & _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& 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 & _OptimVec) + virtual void vectorToParetoSet(const std::vector & _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 & arch; - moeoHyperVolumeDifferenceMetric metric; + MetricT metric; std::vector OptimSet; }; + +/** + Continues until the (feasible or unfeasible) given Pareto set is reached. + + + @ingroup Continuators + */ +template< class MOEOT, class MetricT = moeoDualHyperVolumeDifferenceMetric > +class moeoDualHypContinue: public moeoHypContinue +{ +protected: + bool is_feasible; + + using moeoHypContinue::arch; + using moeoHypContinue::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( const std::vector & _OptimVec, bool _is_feasible, moeoArchive < MOEOT > & _archive, bool _normalize=true, double _rho=1.1 ) + : moeoHypContinue( _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( const std::vector & _OptimVec, bool _is_feasible, moeoArchive < MOEOT > & _archive, bool _normalize=true, ObjectiveVector& _ref_point=NULL ) + : moeoHypContinue( _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& _pop ) + { + std::vector bestCurrentParetoSet = pareto( arch ); + +#ifndef NDEBUG + assert( bestCurrentParetoSet.size() > 0 ); + for( unsigned int i=1; i::pareto; + using moeoHypContinue::is_null_hypervolume; + + /** Translate a vector given as param to the ParetoSet that should be reached. */ + virtual void vectorToParetoSet(const std::vector & _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 diff --git a/moeo/src/core/moeoDualRealObjectiveVector.h b/moeo/src/core/moeoDualRealObjectiveVector.h new file mode 100644 index 000000000..1ed62a8ff --- /dev/null +++ b/moeo/src/core/moeoDualRealObjectiveVector.h @@ -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 + +*/ + +#ifndef _DUALREALOBJECTIVEVECTOR_H_ +#define _DUALREALOBJECTIVEVECTOR_H_ + +#include +#include + +#include + +#include +#include +#include + +template < class ObjectiveVectorTraits, class T = eoMaximizingDualFitness /* can be an eoMinimizingDualFitness */> +class moeoDualRealObjectiveVector : public moeoScalarObjectiveVector +{ + protected: + bool _is_feasible; + + public: + + using moeoScalarObjectiveVector < ObjectiveVectorTraits, T >::size; + using moeoScalarObjectiveVector < ObjectiveVectorTraits, T >::operator[]; + + moeoDualRealObjectiveVector(double value=0.0, bool feasible = false) + : moeoScalarObjectiveVector + ( 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 > 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 +std::ostream & operator<<( std::ostream & _os, const moeoDualRealObjectiveVector & _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 +std::istream & operator>>( std::istream & _is, moeoDualRealObjectiveVector & _objectiveVector ) +{ + _objectiveVector = moeoDualRealObjectiveVector (); + for( unsigned int i=0; i<_objectiveVector.size(); i++ ) { + _is >> _objectiveVector[i]; + } + return _is; +} + + +#endif /*_DUALREALOBJECTIVEVECTOR_H_*/ diff --git a/moeo/src/core/moeoScalarObjectiveVector.h b/moeo/src/core/moeoScalarObjectiveVector.h new file mode 100644 index 000000000..9d1183ad7 --- /dev/null +++ b/moeo/src/core/moeoScalarObjectiveVector.h @@ -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 + +*/ + + +#ifndef MOEOSCALAROBJECTIVEVECTOR_H_ +#define MOEOSCALAROBJECTIVEVECTOR_H_ + +#include +#include +#include +#include +#include + +/** + * 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 > 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_*/ diff --git a/moeo/src/fitness/moeoDominanceDepthFitnessAssignment.h b/moeo/src/fitness/moeoDominanceDepthFitnessAssignment.h index 345048c2c..b07b6b7a1 100644 --- a/moeo/src/fitness/moeoDominanceDepthFitnessAssignment.h +++ b/moeo/src/fitness/moeoDominanceDepthFitnessAssignment.h @@ -1,38 +1,38 @@ /* -* -* 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 -* -*/ + * + * 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 #include #include - +#include /** * 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 sortedptrpop; + sortedptrpop.resize(_pop.size()); + for(unsigned int i=0; i<_pop.size(); i++) + { + sortedptrpop[i] = & (_pop[i]); + } + moeoPtrComparator cmp(objComparator); + std::sort(sortedptrpop.begin(), sortedptrpop.end(), cmp); + + // compute an upper bound on the second objective (1) + double max_obj1 = std::numeric_limits::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 d(_pop.size(), max_obj1); + // initialize fronts + std::vector > fronts(_pop.size()); + // compute rank for each individual + for(unsigned int i=0; i0) + { + 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::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; ifitness(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 > 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 > 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 > 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 > 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 + +template +class moeoExpBinaryIndicatorBasedDualFitnessAssignment : public moeoExpBinaryIndicatorBasedFitnessAssignment +{ +protected: + eoPop _feasible_pop; + eoPop _unfeasible_pop; + +public: + typedef typename MOEOT::ObjectiveVector ObjectiveVector; + typedef typename ObjectiveVector::Type Type; + + using moeoExpBinaryIndicatorBasedFitnessAssignment::values; + + moeoExpBinaryIndicatorBasedDualFitnessAssignment( + moeoNormalizedSolutionVsSolutionBinaryMetric & metric, + const double kappa = 0.05 + ) : moeoExpBinaryIndicatorBasedFitnessAssignment( metric, kappa ) {} + + //! Split up the population in two: in one pop the feasible individual, in the other the feasible ones + virtual void split( eoPop & pop ) + { + _feasible_pop.reserve(pop.size()); + _unfeasible_pop.reserve(pop.size()); + + for( typename eoPop::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* 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; icomputeFitness(i), pop[i].fitness().is_feasible() ); + } + } + + +}; + diff --git a/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h b/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h index a25382f41..d84b052e9 100644 --- a/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h +++ b/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h @@ -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 > values; + std::vector < std::vector > 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 & _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 & _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= 1.0){ + //determine bounds + setup(_set1, _set2); + //determine reference point + for (unsigned int i=0; i unaryMetric(ref_point, bounds); - hypervolume_set1 = unaryMetric(_set1); - hypervolume_set2 = unaryMetric(_set2); + } + else if(normalize) + setup(_set1, _set2); - return hypervolume_set1 - hypervolume_set2; + moeoHyperVolumeMetric 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 +class moeoDualHyperVolumeDifferenceMetric : public moeoHyperVolumeDifferenceMetric +{ +protected: + using moeoHyperVolumeDifferenceMetric::rho; + using moeoHyperVolumeDifferenceMetric::normalize; + using moeoHyperVolumeDifferenceMetric::ref_point; + using moeoHyperVolumeDifferenceMetric::bounds; + +public: + + typedef typename ObjectiveVector::Type Type; + + moeoDualHyperVolumeDifferenceMetric( bool _normalize=true, double _rho=1.1) + : moeoHyperVolumeDifferenceMetric(_normalize, _rho) + { + + } + + moeoDualHyperVolumeDifferenceMetric( bool _normalize/*=true*/, ObjectiveVector& _ref_point/*=NULL*/ ) + : moeoHyperVolumeDifferenceMetric( _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 unaryMetric(ref_point, bounds); + hypervolume_set1 = unaryMetric(_set1); + hypervolume_set2 = unaryMetric(_set2); + + return hypervolume_set1 - hypervolume_set2; + } +}; + #endif /*MOEOHYPERVOLUMEMETRIC_H_*/ diff --git a/moeo/src/metric/moeoHyperVolumeMetric.h b/moeo/src/metric/moeoHyperVolumeMetric.h index c5028094e..f59ba19a6 100644 --- a/moeo/src/metric/moeoHyperVolumeMetric.h +++ b/moeo/src/metric/moeoHyperVolumeMetric.h @@ -152,7 +152,7 @@ class moeoHyperVolumeMetric : public moeoVectorUnaryMetric < ObjectiveVector , d if(_set.size() < 1) throw("Error in moeoHyperVolumeUnaryMetric::setup -> argument1: vector 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 & _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 #include #include +#include #include +#include #include #include @@ -125,6 +127,7 @@ #include #include #include +#include #include #include #include diff --git a/smp/src/island.h b/smp/src/island.h index 9e8e30edd..752b671ef 100644 --- a/smp/src/island.h +++ b/smp/src/island.h @@ -132,7 +132,7 @@ public: */ virtual void receive(void); - AIsland clone() const; + //AIsland clone() const; protected: