From 83673d48b21380944e7ebf42004ff178edfa4ece Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Wed, 12 Jun 2013 09:45:35 +0200 Subject: [PATCH 01/19] bugfix: clear previous pop when calling split --- ...inaryIndicatorBasedDualFitnessAssignment.h | 69 ++++++++++--------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h index bff35769c..251e590ae 100644 --- a/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h +++ b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h @@ -19,27 +19,12 @@ public: 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) + virtual void operator()( eoPop& pop ) { // separate the pop in the members split( pop ); @@ -57,26 +42,48 @@ public: this->setFitnesses(*ppop); } + +protected: + + //! Split up the population in two: in one pop the feasible individual, in the other the feasible ones + virtual void split( eoPop & pop ) + { + // clear previously used populations + _feasible_pop.clear(); + _unfeasible_pop.clear(); + _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 ); + } + } + } + /** * Compute every indicator value in values (values[i] = I(_v[i], _o)) * @param _pop the population */ - void computeValues(const eoPop < MOEOT > & _pop) + virtual 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() ); - } - } - } + values.clear(); + values.resize(pop.size()); + for (unsigned int i=0; i & pop) From a7134a658c882c5a40efb31fea1bb514b91daab1 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Wed, 12 Jun 2013 09:50:46 +0200 Subject: [PATCH 02/19] Correct types for fitness assignment in IBEA While the default fitness assignment of IBEA is the Exp indicator one, the used interface is a binary indicator. --- moeo/src/algo/moeoIBEA.h | 8 ++++---- .../moeoExpBinaryIndicatorBasedFitnessAssignment.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/moeo/src/algo/moeoIBEA.h b/moeo/src/algo/moeoIBEA.h index 928e8f5a0..7af91058b 100644 --- a/moeo/src/algo/moeoIBEA.h +++ b/moeo/src/algo/moeoIBEA.h @@ -160,7 +160,7 @@ public: * @param _op variation operators * @param _fitnessAssignment fitness assignment */ - moeoIBEA (eoContinue < MOEOT > & _continuator, eoPopEvalFunc < MOEOT > & _popEval, eoGenOp < MOEOT > & _op, moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >& _fitnessAssignment) : + moeoIBEA (eoContinue < MOEOT > & _continuator, eoPopEvalFunc < MOEOT > & _popEval, eoGenOp < MOEOT > & _op, moeoBinaryIndicatorBasedFitnessAssignment < 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) {} @@ -173,7 +173,7 @@ public: * @param _op variation operators * @param _fitnessAssignment fitness assignment */ - moeoIBEA (eoContinue < MOEOT > & _continuator, eoEvalFunc < MOEOT > & _eval, eoGenOp < MOEOT > & _op, moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >& _fitnessAssignment) : + moeoIBEA (eoContinue < MOEOT > & _continuator, eoEvalFunc < MOEOT > & _eval, eoGenOp < MOEOT > & _op, moeoBinaryIndicatorBasedFitnessAssignment < 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) {} @@ -190,7 +190,7 @@ public: * Apply the algorithm to the population _pop until the stopping criteria is satified. * @param _pop the population */ - virtual void operator () (eoPop < MOEOT > &_pop) + virtual void operator() (eoPop < MOEOT > &_pop) { eoPop < MOEOT > offspring, empty_pop; popEval (empty_pop, _pop); // a first eval of _pop @@ -260,7 +260,7 @@ protected: /** breeder */ eoBreed < MOEOT > & breed; /** fitness assignment used in IBEA */ - moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >& fitnessAssignment; + moeoBinaryIndicatorBasedFitnessAssignment < MOEOT >& fitnessAssignment; moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >* default_fitnessAssignment; /** dummy diversity assignment */ moeoDummyDiversityAssignment < MOEOT > diversityAssignment; diff --git a/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h b/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h index d84b052e9..cbcbb33c4 100644 --- a/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h +++ b/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h @@ -175,7 +175,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB * Compute every indicator value in values (values[i] = I(_v[i], _o)) * @param _pop the population */ - void computeValues(const eoPop < MOEOT > & _pop) + virtual void computeValues(const eoPop < MOEOT > & _pop) { values.clear(); values.resize(_pop.size()); @@ -211,7 +211,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB * Returns the fitness value of the _idx th individual of the population * @param _idx the index */ - Type computeFitness(const unsigned int _idx) + virtual Type computeFitness(const unsigned int _idx) { Type result(0.0); for (unsigned int i=0; i Date: Wed, 12 Jun 2013 10:14:02 +0200 Subject: [PATCH 03/19] Makes operator() of Hypcontinues virtual when inheritating --- moeo/src/metric/moeoHyperVolumeDifferenceMetric.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h b/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h index aaa899827..64a001281 100644 --- a/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h +++ b/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h @@ -84,7 +84,7 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric < * @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) + virtual double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) { double hypervolume_set1; @@ -228,7 +228,7 @@ public: * @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) + virtual double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) { #ifndef NDEBUG // the two sets must be homogeneous in feasibility From 0badb71c6580f2acae6b203cdde3310ee88f3203 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Wed, 12 Jun 2013 10:37:30 +0200 Subject: [PATCH 04/19] reorder members, for safe initialization --- moeo/src/algo/moeoIBEA.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moeo/src/algo/moeoIBEA.h b/moeo/src/algo/moeoIBEA.h index 7af91058b..b8170a08e 100644 --- a/moeo/src/algo/moeoIBEA.h +++ b/moeo/src/algo/moeoIBEA.h @@ -260,8 +260,8 @@ protected: /** breeder */ eoBreed < MOEOT > & breed; /** fitness assignment used in IBEA */ - moeoBinaryIndicatorBasedFitnessAssignment < MOEOT >& fitnessAssignment; moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >* default_fitnessAssignment; + moeoBinaryIndicatorBasedFitnessAssignment < MOEOT >& fitnessAssignment; /** dummy diversity assignment */ moeoDummyDiversityAssignment < MOEOT > diversityAssignment; /** environmental replacement */ From 557b24694a674bd5d041eb41ab22e00d4fa6c277 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Wed, 12 Jun 2013 10:38:34 +0200 Subject: [PATCH 05/19] Do not declare unused variable This silents warnings about unused variables --- moeo/src/diversity/moeoDummyDiversityAssignment.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moeo/src/diversity/moeoDummyDiversityAssignment.h b/moeo/src/diversity/moeoDummyDiversityAssignment.h index f36a75252..b233f3863 100644 --- a/moeo/src/diversity/moeoDummyDiversityAssignment.h +++ b/moeo/src/diversity/moeoDummyDiversityAssignment.h @@ -74,7 +74,7 @@ class moeoDummyDiversityAssignment : public moeoDiversityAssignment < MOEOT > * @param _pop the population * @param _objVec the objective vector */ - void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec) + void updateByDeleting(eoPop < MOEOT > & /*_pop*/, ObjectiveVector & /*_objVec*/) { // nothing to do... ;-) } From 9250e0c3a511ffe9d6e696219a19b90948bc058c Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Wed, 12 Jun 2013 10:39:23 +0200 Subject: [PATCH 06/19] Backport feasability when computing fitness in fitness assignment --- ...ExpBinaryIndicatorBasedDualFitnessAssignment.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h index 251e590ae..793c6191a 100644 --- a/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h +++ b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h @@ -45,6 +45,8 @@ public: protected: + using moeoExpBinaryIndicatorBasedFitnessAssignment::kappa; + //! Split up the population in two: in one pop the feasible individual, in the other the feasible ones virtual void split( eoPop & pop ) { @@ -94,6 +96,19 @@ protected: } } + virtual Type computeFitness(const unsigned int _idx) + { + Type result( 0.0, values[_idx][_idx].is_feasible() ); + for (unsigned int i=0; i Date: Wed, 12 Jun 2013 10:40:20 +0200 Subject: [PATCH 07/19] In hyp continue, do not declare unused variable and group using --- moeo/src/continue/moeoHypContinue.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/moeo/src/continue/moeoHypContinue.h b/moeo/src/continue/moeoHypContinue.h index f6fbac34a..228006d3a 100644 --- a/moeo/src/continue/moeoHypContinue.h +++ b/moeo/src/continue/moeoHypContinue.h @@ -73,7 +73,7 @@ public: /** Returns false when a ParetoSet is reached. */ - virtual bool operator() ( const eoPop& _pop ) + virtual bool operator() ( const eoPop& /*_pop*/ ) { std::vector bestCurrentParetoSet = pareto( arch ); @@ -143,6 +143,9 @@ protected: using moeoHypContinue::arch; using moeoHypContinue::OptimSet; + using moeoHypContinue::pareto; + using moeoHypContinue::is_null_hypervolume; + public: typedef typename MOEOT::ObjectiveVector ObjectiveVector; typedef typename ObjectiveVector::Type AtomType; @@ -174,7 +177,7 @@ public: } /** Returns false when a ParetoSet is reached. */ - virtual bool operator() ( const eoPop& _pop ) + virtual bool operator() ( const eoPop& /*_pop*/ ) { std::vector bestCurrentParetoSet = pareto( arch ); @@ -196,9 +199,6 @@ public: protected: - using moeoHypContinue::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) { From 4af7f3d1bc873677aee9c3377a4df679c9e9f5b7 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 09:45:29 +0200 Subject: [PATCH 08/19] Allow scalar init of dual fitness; add a pop splitter Scalar init of a dual fitness is dangerous, thus adds an explicit security against use of a partially initialized object. Use the pop splitter in the dual stat switch and in the MOEO dual fitness assignment. --- eo/src/eoDualFitness.h | 155 ++++++++++++------ ...inaryIndicatorBasedDualFitnessAssignment.h | 44 ++--- 2 files changed, 124 insertions(+), 75 deletions(-) diff --git a/eo/src/eoDualFitness.h b/eo/src/eoDualFitness.h index 59d6f6d05..da70e760a 100644 --- a/eo/src/eoDualFitness.h +++ b/eo/src/eoDualFitness.h @@ -74,6 +74,25 @@ protected: //! Flag that marks if the individual is feasible bool _is_feasible; + /** Flag to prevent partial initialization + * + * The reason behind the use of this flag is a bit complicated. + * Normally, we would not want to allow initialization on a scalar. + * But in MOEO, this would necessitate to re-implement most of the + * operator computing metrics, as they expect generic scalars. + * + * As this would be too much work, we use derived metric classes and + * overload them so that they initialize dual fitnesses with the + * feasibility flag. But the compiler still must compile the base + * methods, that use the scalar interface. + * + * Thus, eoDualFitness has a scalar interface, but this flag add a + * security against partial initialization. In DEBUG mode, asserts + * will fail if the feasibility has not been explicitly initialized + * at runtime. + */ + bool _feasible_init; + public: //! Empty initialization @@ -82,58 +101,71 @@ public: */ eoDualFitness() : _value(0.0), - _is_feasible(false) + _is_feasible(false), + _feasible_init(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 + * If you use this interface, you MUST set the feasibility BEFORE + * asking for it or the value. Or else, an assert will fail in debug mode. */ template eoDualFitness( T value ) : _value(value), - _is_feasible(false) + _is_feasible(false), + _feasible_init(false) { - assert( _value == 0 ); } //! Copy constructor eoDualFitness(const eoDualFitness& other) : _value(other._value), - _is_feasible(other._is_feasible) + _is_feasible(other._is_feasible), + _feasible_init(true) {} //! Constructor from explicit value/feasibility eoDualFitness(const BaseType& v, const bool& is_feasible) : _value(v), - _is_feasible(is_feasible) + _is_feasible(is_feasible), + _feasible_init(true) {} //! From a std::pair (first element is the value, second is the feasibility) eoDualFitness(const std::pair& dual) : _value(dual.first), - _is_feasible(dual.second) + _is_feasible(dual.second), + _feasible_init(true) {} - // FIXME is it a good idea to include implicit conversion here? /** Conversion operator: it permits to use a fitness instance as its scalar * type, if needed. For example, this is possible: * eoDualFitness > fit; * double val = 1.0; * val = fit; */ - operator BaseType(void) const { return _value; } + operator BaseType(void) const { return _value; } inline bool is_feasible() const { + assert( _feasible_init ); return _is_feasible; } + //! Explicitly set the feasibility. Useful if you have used previously the instantiation on a single scalar. + inline void is_feasible( bool feasible ) + { + this->is_feasible( feasible ); + this->_feasible_init = true; + } + inline BaseType value() const { + assert( _feasible_init ); return _value; } @@ -141,7 +173,7 @@ public: eoDualFitness& operator=( const std::pair& v ) { this->_value = v.first; - this->_is_feasible = v.second; + this->is_feasible( v.second ); return *this; } @@ -151,21 +183,20 @@ public: { if (this != &other) { this->_value = other._value; - this->_is_feasible = other._is_feasible; + this->is_feasible( other.is_feasible() ); } return *this; } - /* //! Copy operator from a scalar template eoDualFitness& operator=(const T v) { this->_value = v; this->_is_feasible = false; + this->_feasible_init = false; return *this; } - */ //! Comparison that separate feasible individuals from unfeasible ones. Feasible are always better /*! @@ -178,11 +209,11 @@ public: // am I better (less, by default) than the other ? // if I'm feasible and the other is not - if( this->_is_feasible && !other._is_feasible ) { + if( this->is_feasible() && !other.is_feasible() ) { // no, the other has a better fitness return false; - } else if( !this->_is_feasible && other._is_feasible ) { + } else if( !this->is_feasible() && other.is_feasible() ) { // yes, a feasible fitness is always better than an unfeasible one return true; @@ -322,7 +353,7 @@ public: friend std::ostream& operator<<( std::ostream& os, const eoDualFitness & fitness ) { - os << fitness._value << " " << fitness._is_feasible; + os << fitness._value << " " << fitness.is_feasible(); return os; } @@ -337,7 +368,7 @@ public: is >> feasible; fitness._value = value; - fitness._is_feasible = feasible; + fitness.is_feasible( feasible ); return is; } }; @@ -355,18 +386,72 @@ template< class EOT> bool eoIsFeasible ( const EOT & sol ) { return sol.fitness().is_feasible(); } +/** Separate the population into two: one with only feasible individuals, the other with unfeasible ones. + */ +template +class eoDualPopSplit : public eoUF&, void> +{ +protected: + eoPop _pop_feasible; + eoPop _pop_unfeasible; + +public: + //! Split the pop and keep them in members + void operator()( const eoPop& pop ) + { + _pop_feasible.clear(); + _pop_feasible.reserve(pop.size()); + + _pop_unfeasible.clear(); + _pop_unfeasible.reserve(pop.size()); + + for( typename eoPop::const_iterator ieot=pop.begin(), iend=pop.end(); ieot!=iend; ++ieot ) { + /* + if( ieot->invalid() ) { + eo::log << eo::errors << "ERROR: trying to access to an invalid fitness" << std::endl; + } + */ + if( ieot->fitness().is_feasible() ) { + _pop_feasible.push_back( *ieot ); + } else { + _pop_unfeasible.push_back( *ieot ); + } + } + } + + //! Merge feasible and unfeasible populations into a new one + eoPop merge() const + { + eoPop merged; + merged.reserve( _pop_feasible.size() + _pop_unfeasible.size() ); + std::copy( _pop_feasible.begin(), _pop_feasible.end(), std::back_inserter >(merged) ); + std::copy( _pop_unfeasible.begin(), _pop_unfeasible.end(), std::back_inserter >(merged) ); + return merged; + } + + eoPop& feasible() { return _pop_feasible; } + eoPop& unfeasible() { return _pop_unfeasible; } +}; + + /** Embed two eoStat and call the first one on the feasible individuals and * the second one on the unfeasible ones, merge the two resulting value in * a string, separated by a given marker. */ -//template template class eoDualStatSwitch : public eoStat< EOT, std::string > { +protected: + EOSTAT & _stat_feasible; + EOSTAT & _stat_unfeasible; + + std::string _sep; + + eoDualPopSplit _pop_split; + public: using eoStat::value; -// eoDualStatSwitch( eoStat & stat_feasible, eoStat & stat_unfeasible, std::string sep=" " ) : eoDualStatSwitch( EOSTAT & stat_feasible, EOSTAT & stat_unfeasible, std::string sep=" " ) : eoStat( "?"+sep+"?", @@ -379,41 +464,17 @@ public: virtual void operator()( const eoPop & pop ) { - eoPop pop_feasible; - pop_feasible.reserve(pop.size()); + // create two separated pop in this operator + _pop_split( pop ); - eoPop pop_unfeasible; - pop_unfeasible.reserve(pop.size()); - - for( typename eoPop::const_iterator ieot=pop.begin(), iend=pop.end(); ieot!=iend; ++ieot ) { - /* - if( ieot->invalid() ) { - eo::log << eo::errors << "ERROR: trying to access to an invalid fitness" << std::endl; - } - */ - if( ieot->fitness().is_feasible() ) { - pop_feasible.push_back( *ieot ); - } else { - pop_unfeasible.push_back( *ieot ); - } - } - - _stat_feasible( pop_feasible ); - _stat_unfeasible( pop_unfeasible ); + _stat_feasible( _pop_split.feasible() ); + _stat_unfeasible( _pop_split.unfeasible() ); std::ostringstream out; out << _stat_feasible.value() << _sep << _stat_unfeasible.value(); value() = out.str(); } - -protected: -// eoStat & _stat_feasible; -// eoStat & _stat_unfeasible; - EOSTAT & _stat_feasible; - EOSTAT & _stat_unfeasible; - - std::string _sep; }; /** @} */ diff --git a/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h index 793c6191a..0fce27148 100644 --- a/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h +++ b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h @@ -1,12 +1,14 @@ +#ifndef MOEOEXPBINARYINDICATORBASEDDUALFITNESSASSIGNMENT_H_ +#define MOEOEXPBINARYINDICATORBASEDDUALFITNESSASSIGNMENT_H_ + #include template class moeoExpBinaryIndicatorBasedDualFitnessAssignment : public moeoExpBinaryIndicatorBasedFitnessAssignment { protected: - eoPop _feasible_pop; - eoPop _unfeasible_pop; + eoDualPopSplit _pop_split; public: typedef typename MOEOT::ObjectiveVector ObjectiveVector; @@ -26,20 +28,24 @@ public: */ virtual void operator()( eoPop& pop ) { - // separate the pop in the members - split( pop ); + // separate the pop in feasible/unfeasible + _pop_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; + // if there is at least one feasible individual, + // it will supersede all the unfeasible ones + if( _pop_split.feasible().size() == 0 ) { + ppop = & _pop_split.unfeasible(); } else { - ppop = & _feasible_pop; + ppop = & _pop_split.feasible(); } this->setup(*ppop); this->computeValues(*ppop); - this->setFitnesses(*ppop); + this->setFitnesses(*ppop); // NOTE: this alter individuals + + // bring back altered individuals in the pop + pop = _pop_split.merge(); } @@ -47,25 +53,6 @@ protected: using moeoExpBinaryIndicatorBasedFitnessAssignment::kappa; - //! Split up the population in two: in one pop the feasible individual, in the other the feasible ones - virtual void split( eoPop & pop ) - { - // clear previously used populations - _feasible_pop.clear(); - _unfeasible_pop.clear(); - _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 ); - } - } - } - /** * Compute every indicator value in values (values[i] = I(_v[i], _o)) * @param _pop the population @@ -112,3 +99,4 @@ protected: }; +#endif // MOEOEXPBINARYINDICATORBASEDDUALFITNESSASSIGNMENT_H_ From c44264e703e5daafe4243217185c21b01adaff15 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 10:00:15 +0200 Subject: [PATCH 09/19] Move the hyper volume dual difference metric in a separated file --- .../moeoDualHyperVolumeDifferenceMetric.h | 117 ++++++++++++++++++ .../metric/moeoHyperVolumeDifferenceMetric.h | 86 ------------- 2 files changed, 117 insertions(+), 86 deletions(-) create mode 100644 moeo/src/metric/moeoDualHyperVolumeDifferenceMetric.h diff --git a/moeo/src/metric/moeoDualHyperVolumeDifferenceMetric.h b/moeo/src/metric/moeoDualHyperVolumeDifferenceMetric.h new file mode 100644 index 000000000..b7774bb51 --- /dev/null +++ b/moeo/src/metric/moeoDualHyperVolumeDifferenceMetric.h @@ -0,0 +1,117 @@ +/* + +(c) 2013 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 MOEODUALHYPERVOLUMEDIFFERENCEMETRIC_H_ +#define MOEODUALHYPERVOLUMEDIFFERENCEMETRIC_H_ + +#include + + +template +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 + */ + virtual 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 /*MOEODUALHYPERVOLUMEDIFFERENCEMETRIC_H_*/ diff --git a/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h b/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h index 64a001281..ad3336cd7 100644 --- a/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h +++ b/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h @@ -197,90 +197,4 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric < }; - -template -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 - */ - virtual 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_*/ From 32b4f077c4ee70d64dd616518e98710967950891 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 10:36:33 +0200 Subject: [PATCH 10/19] Move the dual hypervolume continuator in a separated file --- moeo/src/continue/moeoDualHypContinue.h | 121 ++++++++++++++++++++++++ moeo/src/continue/moeoHypContinue.h | 111 ++++------------------ 2 files changed, 139 insertions(+), 93 deletions(-) create mode 100644 moeo/src/continue/moeoDualHypContinue.h diff --git a/moeo/src/continue/moeoDualHypContinue.h b/moeo/src/continue/moeoDualHypContinue.h new file mode 100644 index 000000000..99c33d45f --- /dev/null +++ b/moeo/src/continue/moeoDualHypContinue.h @@ -0,0 +1,121 @@ +/* + +(c) 2013 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 _moeoDualHypContinue_h +#define _moeoDualHypContinue_h + +#include + +/** + 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; + + using moeoHypContinue::pareto; + using moeoHypContinue::is_null_hypervolume; + +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 & _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/continue/moeoHypContinue.h b/moeo/src/continue/moeoHypContinue.h index 228006d3a..bbc1a799b 100644 --- a/moeo/src/continue/moeoHypContinue.h +++ b/moeo/src/continue/moeoHypContinue.h @@ -36,7 +36,6 @@ //----------------------------------------------------------------------------- - #ifndef _moeoHypContinue_h #define _moeoHypContinue_h @@ -60,17 +59,29 @@ public: /// Ctor moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, double _rho=1.1) - : eoContinue(), arch(_archive), metric(_normalize,_rho) + : eoContinue(), arch(_archive), default_metric(new MetricT(_normalize,_rho)), metric(*default_metric) { vectorToParetoSet(_OptimVec); } moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, ObjectiveVector& _ref_point=NULL) - : eoContinue (), arch(_archive), metric(_normalize,_ref_point) + : eoContinue(), arch(_archive), default_metric(new MetricT(_normalize,_ref_point)), metric(*default_metric) { vectorToParetoSet(_OptimVec); } + moeoHypContinue( MetricT& _metric, const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive ) + : eoContinue(), arch(_archive), default_metric(NULL), metric(_metric) + { + vectorToParetoSet(_OptimVec); + } + + ~moeoHypContinue() + { + if( default_metric != NULL ) { + delete default_metric; + } + } /** Returns false when a ParetoSet is reached. */ virtual bool operator() ( const eoPop& /*_pop*/ ) @@ -88,8 +99,8 @@ protected: { std::vector < ObjectiveVector > bestCurrentParetoSet; - for (size_t i=0; i & arch; - MetricT metric; + MetricT* default_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; - - using moeoHypContinue::pareto; - using moeoHypContinue::is_null_hypervolume; - -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 & _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 From b132f48de2ed7f36570dbb1bdd9fbf26f4493984 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 10:37:25 +0200 Subject: [PATCH 11/19] Insert a copyright header --- ...inaryIndicatorBasedDualFitnessAssignment.h | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h index 0fce27148..78c3d08fe 100644 --- a/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h +++ b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h @@ -1,3 +1,28 @@ +/* + +(c) 2013 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 MOEOEXPBINARYINDICATORBASEDDUALFITNESSASSIGNMENT_H_ #define MOEOEXPBINARYINDICATORBASEDDUALFITNESSASSIGNMENT_H_ From 70aa40f8887deafeafb3fc530093b654b8ab4937 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 10:37:48 +0200 Subject: [PATCH 12/19] Add dual hypervolume operators in the framewok header --- moeo/src/moeo | 2 ++ 1 file changed, 2 insertions(+) diff --git a/moeo/src/moeo b/moeo/src/moeo index eae7add7f..bc7282ffa 100644 --- a/moeo/src/moeo +++ b/moeo/src/moeo @@ -144,6 +144,7 @@ #include #include #include +#include #include #include #include @@ -217,5 +218,6 @@ #include #include +#include #endif /*MOEO_*/ From 272342bc16dd198a728756a6c24d4059be5149c3 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 14:44:02 +0200 Subject: [PATCH 13/19] Abstract base class for wrapping an estimator and a sampler as an eoTransform --- edo/src/edoTransform.h | 111 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 edo/src/edoTransform.h diff --git a/edo/src/edoTransform.h b/edo/src/edoTransform.h new file mode 100644 index 000000000..20421d5b1 --- /dev/null +++ b/edo/src/edoTransform.h @@ -0,0 +1,111 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution algorithms. + +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; either +version 2.1 of the License, or (at your option) any later version. + +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright (C) 2013 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _edoTransform_h +#define _edoTransform_h + +#include // eoTransform + +/** @defgroup Wrappers + * + * Wrappers to interact with other parts of the framework + */ + +/** Abstract base class for wrapping an estimator and a sampler as an eoTransform + * + * @ingroup Wrappers + */ +template +class edoTransform : public eoTransform< eoPop& > +{ +public: + typedef typename D::EOType EOType; + + edoTransform( edoEstimator & estimator, edoSampler & sampler ) : + _estimator(estimator), _sampler(sampler) + {} + + virtual void operator()( eoPop & pop ) = 0; + +protected: + edoEstimator & _estimator; + edoSampler & _sampler; +}; + + +/** Wrapping an estimator and a sampler as an eoTransform. + * + * @ingroup Wrappers + */ +template +class edoTransformAdaptive : public edoTransform +{ +public: + typedef typename D::EOType EOType; + + edoTransformAdaptive( D & distrib, edoEstimator & estimator, edoSampler & sampler ) + : _distrib(distrib), _estimator(estimator), _sampler(sampler) + {} + + virtual void operator()( eoPop & pop ) + { + _distrib = _estimator( pop ); + pop.clear(); + for( unsigned int i = 0; i < pop.size(); ++i ) { + pop.push_back( _sampler(_distrib) ); + } + } + +protected: + D & _distrib; + edoEstimator & _estimator; + edoSampler & _sampler; +}; + + +/** Wrapping an estimator and a sampler as an eoTransform, + * the distribution is created at instanciation and replaced at each call. + * + * @ingroup Wrappers + */ +template +class edoTransformStateless : public edoTransformAdaptive +{ +public: + typedef typename D::EOType EOType; + + edoTransformStateless( edoEstimator & estimator, edoSampler & sampler ) + : edoTransformAdaptive( *(new D), estimator, sampler ) + {} + + ~edoTransformStateless() + { + // delete the temporary distrib allocated in constructor + delete &(this->_distrib); + } +}; + +#endif // !_edoTransform_h From 67e4bb01fd1a403e253ddf747e5c6a966450fbc1 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 14:45:51 +0200 Subject: [PATCH 14/19] Use EOType as a ref to the template in stats --- eo/src/eoDualFitness.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/eo/src/eoDualFitness.h b/eo/src/eoDualFitness.h index da70e760a..ff952db66 100644 --- a/eo/src/eoDualFitness.h +++ b/eo/src/eoDualFitness.h @@ -438,22 +438,24 @@ public: * the second one on the unfeasible ones, merge the two resulting value in * a string, separated by a given marker. */ -template -class eoDualStatSwitch : public eoStat< EOT, std::string > +template +class eoDualStatSwitch : public eoStat< typename EOSTAT::EOType, std::string > { +public: + typedef typename EOSTAT::EOType EOType; protected: EOSTAT & _stat_feasible; EOSTAT & _stat_unfeasible; std::string _sep; - eoDualPopSplit _pop_split; + eoDualPopSplit _pop_split; public: - using eoStat::value; + using eoStat::value; eoDualStatSwitch( EOSTAT & stat_feasible, EOSTAT & stat_unfeasible, std::string sep=" " ) : - eoStat( + eoStat( "?"+sep+"?", stat_feasible.longName()+sep+stat_unfeasible.longName() ), @@ -462,7 +464,7 @@ public: _sep(sep) { } - virtual void operator()( const eoPop & pop ) + virtual void operator()( const eoPop & pop ) { // create two separated pop in this operator _pop_split( pop ); From f4b71dffadfec840c4bbfd29f7471a6ae0659d5d Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 14:48:00 +0200 Subject: [PATCH 15/19] Add a warning when computing stat in empty pop --- eo/src/utils/eoStat.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eo/src/utils/eoStat.h b/eo/src/utils/eoStat.h index fd26ec228..ccf3c4137 100644 --- a/eo/src/utils/eoStat.h +++ b/eo/src/utils/eoStat.h @@ -40,6 +40,7 @@ Contact: http://eodev.sourceforge.net #include #include //#include +#include /** @defgroup Stats Statistics computation * @@ -485,7 +486,8 @@ public: virtual void operator()( const eoPop & _pop ) { if( _pop.size() == 0 ) { - // how to implement value() = 0 ? + //FIXME how to implement value() = 0 ? + eo::log << eo::warnings << "Called " << className() << " on an empty pop, value unchanged" << std::endl; } else { eoPop pop = _pop; From 8679da695c288af5214df5b595e01a9668e28532 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 14:48:40 +0200 Subject: [PATCH 16/19] Add a reference to the template type in eoStat --- eo/src/utils/eoStat.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eo/src/utils/eoStat.h b/eo/src/utils/eoStat.h index ccf3c4137..e44eff33d 100644 --- a/eo/src/utils/eoStat.h +++ b/eo/src/utils/eoStat.h @@ -85,6 +85,7 @@ template class eoStat : public eoValueParam, public eoStatBase { public: + typedef EOT EOType; eoStat(T _value, std::string _description) : eoValueParam(_value, _description) @@ -121,6 +122,7 @@ template class eoSortedStat : public eoSortedStatBase, public eoValueParam { public : + typedef EOT EOType; eoSortedStat(ParamType _value, std::string _desc) : eoValueParam(_value, _desc) {} virtual std::string className(void) const { return "eoSortedStat"; } From 819c2c3106376e13228fa72053332c0d7675197e Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 14:49:08 +0200 Subject: [PATCH 17/19] [COMPATIBILITY] Remove a unused parameter in eoInterquartileRangeStat constructor --- eo/src/utils/eoStat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eo/src/utils/eoStat.h b/eo/src/utils/eoStat.h index e44eff33d..ae2569ab7 100644 --- a/eo/src/utils/eoStat.h +++ b/eo/src/utils/eoStat.h @@ -483,7 +483,7 @@ class eoInterquartileRangeStat : public eoStat< EOT, typename EOT::Fitness > public: using eoStat::value; - eoInterquartileRangeStat( typename EOT::Fitness start, std::string description = "IQR" ) : eoStat( start, description ) {} + eoInterquartileRangeStat( std::string description = "IQR" ) : eoStat( 0.0, description ) {} virtual void operator()( const eoPop & _pop ) { From 0c82be47df56cd913794446c438afba988def763 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 14:50:08 +0200 Subject: [PATCH 18/19] Add an Nth element stat to compute median without sorting the pop --- eo/src/utils/eoStat.h | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/eo/src/utils/eoStat.h b/eo/src/utils/eoStat.h index ae2569ab7..7099470cd 100644 --- a/eo/src/utils/eoStat.h +++ b/eo/src/utils/eoStat.h @@ -475,6 +475,51 @@ public : }; */ +//! A robust measure of the mass (generally used to compute the median). Do not alter the given pop. +template +class eoNthElementStat : public eoStat< EOT, typename EOT::Fitness > +{ +protected: + int _nth; + double _ratio; + +public: + using eoStat::value; + + eoNthElementStat( int nth = 0, std::string description = "NthElement") + : eoStat( 0.0, description ), _nth(nth), _ratio(-1.0) + {} + + eoNthElementStat( double ratio = 0.5, std::string description = "Median" ) + : eoStat( 0.0, description ), _nth(-1), _ratio(ratio) + {} + + virtual void operator()( const eoPop & _pop ) + { + if( _nth == -1 ) { // asked for a ratio + _nth = static_cast( std::floor(_pop.size() * _ratio) ); + } else { + assert( _ratio == -1 ); // asked for a position + } + + if( _pop.size() == 0 ) { + //FIXME how to implement value() = 0 ? + eo::log << eo::warnings << "Called " << className() << " on an empty pop, value unchanged" << std::endl; + + } else { + eoPop pop = _pop; // copy, thus no sorting of the original pop + + std::nth_element( pop.begin(), pop.begin()+_nth, pop.end() ); + value() = pop[_nth].fitness(); + } + } + + virtual std::string className(void) const { return "eoNthElementStat"; } +}; +/** @example t-eoIQRStat.cpp + */ + + //! A robust measure of dispersion (also called midspread or middle fifty) that is the difference between the third and the first quartile. template From 6fa57622bed9c845ed7b6e3c3dfdde9eafe13911 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Thu, 13 Jun 2013 14:50:44 +0200 Subject: [PATCH 19/19] Missing header and include guards for moeoBinaryMetricStat --- moeo/src/utils/moeoBinaryMetricStat.h | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/moeo/src/utils/moeoBinaryMetricStat.h b/moeo/src/utils/moeoBinaryMetricStat.h index f60d20c29..42b34ff11 100644 --- a/moeo/src/utils/moeoBinaryMetricStat.h +++ b/moeo/src/utils/moeoBinaryMetricStat.h @@ -1,5 +1,38 @@ +/* +(c) 2013 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 _MOEOBINARYMETRICSTAT_H_ +#define _MOEOBINARYMETRICSTAT_H_ + +#include + +/** A wrapper to save a moeoMetric in an eoStat + * + * This wrap a MOEO binary metric into an eoStat + * This is useful if you want to use it in a checkpoint, for instance. + */ template class moeoBinaryMetricStat : public eoStat { @@ -57,3 +90,5 @@ protected: bool _first_gen; }; + +#endif // _MOEOBINARYMETRICSTAT_H_