diff --git a/trunk/paradiseo-moeo/src/metric/moeoBinaryMetricSavingUpdater.h b/trunk/paradiseo-moeo/src/metric/moeoBinaryMetricSavingUpdater.h index 01aadfaa5..b2fb8aa3a 100644 --- a/trunk/paradiseo-moeo/src/metric/moeoBinaryMetricSavingUpdater.h +++ b/trunk/paradiseo-moeo/src/metric/moeoBinaryMetricSavingUpdater.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // moeoBinaryMetricSavingUpdater.h -// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006 +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 /* This library... @@ -19,76 +19,70 @@ #include #include -/** - * This class allows to save the progression of a binary metric comparing the fitness values of the current population (or archive) - * with the fitness values of the population (or archive) of the generation (n-1) into a file +/** + * This class allows to save the progression of a binary metric comparing the objective vectors of the current population (or archive) + * with the objective vectors of the population (or archive) of the generation (n-1) into a file */ -template < class EOT > class moeoBinaryMetricSavingUpdater:public eoUpdater +template < class MOEOT > +class moeoBinaryMetricSavingUpdater : public eoUpdater { public: - /** - * The fitness type of a solution - */ - typedef typename EOT::Fitness EOFitness; + /** + * The objective vector type of a solution + */ + typedef typename MOEOT::ObjectiveVector ObjectiveVector; - /** - * Ctor - * @param _metric the binary metric comparing two Pareto sets - * @param _pop the main population - * @param _filename the target filename - */ - moeoBinaryMetricSavingUpdater (moeoVectorVsVectorBM < EOT, double >&_metric, - const eoPop < EOT > &_pop, - std::string _filename):metric (_metric), - pop (_pop), filename (_filename), counter (1) - { - } + /** + * Ctor + * @param _metric the binary metric comparing two Pareto sets + * @param _pop the main population + * @param _filename the target filename + */ + moeoBinaryMetricSavingUpdater (moeoVectorVsVectorBinaryMetric < ObjectiveVector, double > & _metric, const eoPop < MOEOT > & _pop, std::string _filename) : + metric(_metric), pop(_pop), filename(_filename), counter(1) + {} - /** - * Saves the metric's value for the current generation - */ - void operator () () - { - if (pop.size ()) - { - if (firstGen) - { - firstGen = false; - } - else - { - // creation of the two Pareto sets - std::vector < EOFitness > from; - std::vector < EOFitness > to; - for (unsigned i = 0; i < pop.size (); i++) - from.push_back (pop[i].fitness ()); - for (unsigned i = 0; i < oldPop.size (); i++) - to.push_back (oldPop[i].fitness ()); - // writing the result into the file - std::ofstream f (filename.c_str (), std::ios::app); - f << counter++ << ' ' << metric (from, to) << std::endl; - f.close (); - } - oldPop = pop; - } - } + /** + * Saves the metric's value for the current generation + */ + void operator()() { + if (pop.size()) { + if (firstGen) { + firstGen = false; + } + else { + // creation of the two Pareto sets + std::vector < ObjectiveVector > from; + std::vector < ObjectiveVector > to; + for (unsigned i=0; i&metric; - /** main population */ - const eoPop < EOT > &pop; - /** (n-1) population */ - eoPop < EOT > oldPop; - /** target filename */ - std::string filename; - /** is it the first generation ? */ - bool firstGen; - /** counter */ - unsigned counter; + /** binary metric comparing two Pareto sets */ + moeoVectorVsVectorBinaryMetric < ObjectiveVector, double > & metric; + /** main population */ + const eoPop < MOEOT > & pop; + /** (n-1) population */ + eoPop< MOEOT > oldPop; + /** target filename */ + std::string filename; + /** is it the first generation ? */ + bool firstGen; + /** counter */ + unsigned counter; }; -#endif /*MOEOBINARYMETRICSAVINGUPDATER_H_ */ +#endif /*MOEOBINARYMETRICSAVINGUPDATER_H_*/ diff --git a/trunk/paradiseo-moeo/src/metric/moeoContributionMetric.h b/trunk/paradiseo-moeo/src/metric/moeoContributionMetric.h index 7da5702df..325a11229 100644 --- a/trunk/paradiseo-moeo/src/metric/moeoContributionMetric.h +++ b/trunk/paradiseo-moeo/src/metric/moeoContributionMetric.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // moeoContributionMetric.h -// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006 +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 /* This library... @@ -17,100 +17,82 @@ /** * The contribution metric evaluates the proportion of non-dominated solutions given by a Pareto set relatively to another Pareto set - * * (Meunier, Talbi, Reininger: 'A multiobjective genetic algorithm for radio network optimization', in Proc. of the 2000 Congress on Evolutionary Computation, IEEE Press, pp. 317-324) */ -template < class EOT > class moeoContributionMetric:public moeoVectorVsVectorBM < EOT, - double > +template < class ObjectiveVector > +class moeoContributionMetric : public moeoVectorVsVectorBinaryMetric < ObjectiveVector, double > { public: - /** - * The fitness type of a solution - */ - typedef typename EOT::Fitness EOFitness; - - /** - * Returns the contribution of the Pareto set '_set1' relatively to the Pareto set '_set2' - * @param _set1 the first Pareto set - * @param _set2 the second Pareto set - */ - double operator () (const std::vector < EOFitness > &_set1, - const std::vector < EOFitness > &_set2) - { - unsigned c = card_C (_set1, _set2); - unsigned w1 = card_W (_set1, _set2); - unsigned n1 = card_N (_set1, _set2); - unsigned w2 = card_W (_set2, _set1); - unsigned n2 = card_N (_set2, _set1); - return (double) (c / 2.0 + w1 + n1) / (c + w1 + n1 + w2 + n2); - } + /** + * Returns the contribution of the Pareto set '_set1' relatively to the Pareto set '_set2' + * @param _set1 the first Pareto set + * @param _set2 the second Pareto set + */ + double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) { + unsigned c = card_C(_set1, _set2); + unsigned w1 = card_W(_set1, _set2); + unsigned n1 = card_N(_set1, _set2); + unsigned w2 = card_W(_set2, _set1); + unsigned n2 = card_N(_set2, _set1); + return (double) (c / 2.0 + w1 + n1) / (c + w1 + n1 + w2 + n2); + } private: - /** - * Returns the number of solutions both in '_set1' and '_set2' - * @param _set1 the first Pareto set - * @param _set2 the second Pareto set - */ - unsigned card_C (const std::vector < EOFitness > &_set1, - const std::vector < EOFitness > &_set2) - { - unsigned c = 0; - for (unsigned i = 0; i < _set1.size (); i++) - for (unsigned j = 0; j < _set2.size (); j++) - if (_set1[i] == _set2[j]) - { - c++; - break; - } - return c; - } + /** + * Returns the number of solutions both in '_set1' and '_set2' + * @param _set1 the first Pareto set + * @param _set2 the second Pareto set + */ + unsigned card_C (const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) { + unsigned c=0; + for (unsigned i=0; i<_set1.size(); i++) + for (unsigned j=0; j<_set2.size(); j++) + if (_set1[i] == _set2[j]) { + c++; + break; + } + return c; + } - /** - * Returns the number of solutions in '_set1' dominating at least one solution of '_set2' - * @param _set1 the first Pareto set - * @param _set2 the second Pareto set - */ - unsigned card_W (const std::vector < EOFitness > &_set1, - const std::vector < EOFitness > &_set2) - { - unsigned w = 0; - for (unsigned i = 0; i < _set1.size (); i++) - for (unsigned j = 0; j < _set2.size (); j++) - if (_set1[i].dominates (_set2[j])) - { - w++; - break; - } - return w; - } + /** + * Returns the number of solutions in '_set1' dominating at least one solution of '_set2' + * @param _set1 the first Pareto set + * @param _set2 the second Pareto set + */ + unsigned card_W (const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) { + unsigned w=0; + for (unsigned i=0; i<_set1.size(); i++) + for (unsigned j=0; j<_set2.size(); j++) + if (_set1[i].dominates(_set2[j])) { + w++; + break; + } + return w; + } - /** - * Returns the number of solutions in '_set1' having no relation of dominance with those from '_set2' - * @param _set1 the first Pareto set - * @param _set2 the second Pareto set - */ - unsigned card_N (const std::vector < EOFitness > &_set1, - const std::vector < EOFitness > &_set2) - { - unsigned n = 0; - for (unsigned i = 0; i < _set1.size (); i++) - { - bool domin_rel = false; - for (unsigned j = 0; j < _set2.size (); j++) - if (_set1[i].dominates (_set2[j]) || _set2[j].dominates (_set1[i])) - { - domin_rel = true; - break; - } - if (!domin_rel) - n++; - } - return n; - } + /** + * Returns the number of solutions in '_set1' having no relation of dominance with those from '_set2' + * @param _set1 the first Pareto set + * @param _set2 the second Pareto set + */ + unsigned card_N (const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) { + unsigned n=0; + for (unsigned i=0; i<_set1.size(); i++) { + bool domin_rel = false; + for (unsigned j=0; j<_set2.size(); j++) + if (_set1[i].dominates(_set2[j]) || _set2[j].dominates(_set1 [i])) { + domin_rel = true; + break; + } + if (! domin_rel) + n++; + } + return n; + } }; -#endif /*MOEOCONTRIBUTIONMETRIC_H_ */ +#endif /*MOEOCONTRIBUTIONMETRIC_H_*/ diff --git a/trunk/paradiseo-moeo/src/metric/moeoEntropyMetric.h b/trunk/paradiseo-moeo/src/metric/moeoEntropyMetric.h index e760e35f6..8c3f5c936 100644 --- a/trunk/paradiseo-moeo/src/metric/moeoEntropyMetric.h +++ b/trunk/paradiseo-moeo/src/metric/moeoEntropyMetric.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // moeoEntropyMetric.h -// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006 +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 /* This library... @@ -16,164 +16,162 @@ #include /** - * The entropy gives an idea of the diversity of a Pareto set relatively to another Pareto set - * + * The entropy gives an idea of the diversity of a Pareto set relatively to another * (Basseur, Seynhaeve, Talbi: 'Design of Multi-objective Evolutionary Algorithms: Application to the Flow-shop Scheduling Problem', in Proc. of the 2002 Congress on Evolutionary Computation, IEEE Press, pp. 1155-1156) */ -template < class EOT > class moeoEntropyMetric:public moeoVectorVsVectorBM < EOT, - double > +template < class ObjectiveVector > +class moeoEntropyMetric : public moeoVectorVsVectorBinaryMetric < ObjectiveVector, double > { public: - /** - * The fitness type of a solution - */ - typedef typename EOT::Fitness EOFitness; + /** + * Returns the entropy of the Pareto set '_set1' relatively to the Pareto set '_set2' + * @param _set1 the first Pareto set + * @param _set2 the second Pareto set + */ + double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) { + // normalization + std::vector< ObjectiveVector > set1 = _set1; + std::vector< ObjectiveVector > set2= _set2; + removeDominated (set1); + removeDominated (set2); + prenormalize (set1); + normalize (set1); + normalize (set2); - /** - * Returns the entropy of the Pareto set '_set1' relatively to the Pareto set '_set2' - * @param _set1 the first Pareto set - * @param _set2 the second Pareto set - */ - double operator () (const std::vector < EOFitness > &_set1, - const std::vector < EOFitness > &_set2) - { - // normalization - std::vector < EOFitness > set1 = _set1; - std::vector < EOFitness > set2 = _set2; - removeDominated (set1); - removeDominated (set2); - prenormalize (set1); - normalize (set1); - normalize (set2); + // making of PO* + std::vector< ObjectiveVector > star; // rotf :-) + computeUnion (set1, set2, star); + removeDominated (star); - // making of PO* - std::vector < EOFitness > star; // rotf :-) - computeUnion (set1, set2, star); - removeDominated (star); + // making of PO1 U PO* + std::vector< ObjectiveVector > union_set1_star; // rotf again ... + computeUnion (set1, star, union_set1_star); - // making of PO1 U PO* - std::vector < EOFitness > union_set1_star; // rotf again ... - computeUnion (set1, star, union_set1_star); + unsigned C = union_set1_star.size(); + float omega=0; + float entropy=0; - unsigned C = union_set1_star.size (); - float omega = 0; - float entropy = 0; - - for (unsigned i = 0; i < C; i++) - { - unsigned N_i = - howManyInNicheOf (union_set1_star, union_set1_star[i], - star.size ()); - unsigned n_i = - howManyInNicheOf (set1, union_set1_star[i], star.size ()); - if (n_i > 0) - { - omega += 1.0 / N_i; - entropy += - (float) n_i / (N_i * C) * log (((float) n_i / C) / log (2.0)); - } - } - entropy /= -log (omega); - entropy *= log (2.0); - return entropy; - } + for (unsigned i=0 ; i 0) { + omega += 1.0 / N_i; + entropy += (float) n_i / (N_i * C) * log (((float) n_i / C) / log (2.0)); + } + } + entropy /= - log (omega); + entropy *= log (2.0); + return entropy; + } private: - std::vector < double >vect_min_val; - std::vector < double >vect_max_val; + /** vector of min values */ + std::vector vect_min_val; + /** vector of max values */ + std::vector vect_max_val; - void removeDominated (std::vector < EOFitness > &_f) - { - for (unsigned i = 0; i < _f.size (); i++) - { - bool dom = false; - for (unsigned j = 0; j < _f.size (); j++) - if (i != j && _f[j].dominates (_f[i])) - { - dom = true; - break; - } - if (dom) - { - _f[i] = _f.back (); - _f.pop_back (); - i--; - } - } - } - void prenormalize (const std::vector < EOFitness > &_f) - { - vect_min_val.clear (); - vect_max_val.clear (); + /** + * Removes the dominated individuals contained in _f + * @param _f a Pareto set + */ + void removeDominated(std::vector < ObjectiveVector > & _f) { + for (unsigned i=0 ; i<_f.size(); i++) { + bool dom = false; + for (unsigned j=0; j<_f.size(); j++) + if (i != j && _f[j].dominates(_f[i])) { + dom = true; + break; + } + if (dom) { + _f[i] = _f.back(); + _f.pop_back(); + i--; + } + } + } - for (unsigned char i = 0; i < EOFitness::fitness_traits::nObjectives (); - i++) - { - float min_val = _f.front ()[i], max_val = min_val; - for (unsigned j = 1; j < _f.size (); j++) - { - if (_f[j][i] < min_val) - min_val = _f[j][i]; - if (_f[j][i] > max_val) - max_val = _f[j][i]; - } - vect_min_val.push_back (min_val); - vect_max_val.push_back (max_val); - } - } - void normalize (std::vector < EOFitness > &_f) - { - for (unsigned i = 0; i < EOFitness::fitness_traits::nObjectives (); i++) - for (unsigned j = 0; j < _f.size (); j++) - _f[j][i] = - (_f[j][i] - vect_min_val[i]) / (vect_max_val[i] - vect_min_val[i]); - } + /** + * Prenormalization + * @param _f a Pareto set + */ + void prenormalize (const std::vector< ObjectiveVector > & _f) { + vect_min_val.clear(); + vect_max_val.clear(); - void computeUnion (const std::vector < EOFitness > &_f1, - const std::vector < EOFitness > &_f2, - std::vector < EOFitness > &_f) - { - _f = _f1; - for (unsigned i = 0; i < _f2.size (); i++) - { - bool b = false; - for (unsigned j = 0; j < _f1.size (); j++) - if (_f1[j] == _f2[i]) - { - b = true; - break; - } - if (!b) - _f.push_back (_f2[i]); - } - } + for (unsigned char i=0 ; imax_val) + max_val = _f[j][i]; + } + vect_min_val.push_back(min_val); + vect_max_val.push_back (max_val); + } + } - unsigned howManyInNicheOf (const std::vector < EOFitness > &_f, - const EOFitness & _s, unsigned _size) - { - unsigned n = 0; - for (unsigned i = 0; i < _f.size (); i++) - { - if (euclidianDistance (_f[i], _s) < (_s.size () / (double) _size)) - n++; - } - return n; - } - double euclidianDistance (const EOFitness & _set1, const EOFitness & _to, - unsigned _deg = 2) - { - double dist = 0; - for (unsigned i = 0; i < _set1.size (); i++) - dist += pow (fabs (_set1[i] - _to[i]), (int) _deg); - return pow (dist, 1.0 / _deg); - } + /** + * Normalization + * @param _f a Pareto set + */ + void normalize (std::vector< ObjectiveVector > & _f) { + for (unsigned i=0 ; i & _f1, const std::vector< ObjectiveVector > & _f2, std::vector< ObjectiveVector > & _f) { + _f = _f1 ; + for (unsigned i=0; i<_f2.size(); i++) { + bool b = false; + for (unsigned j=0; j<_f1.size(); j ++) + if (_f1[j] == _f2[i]) { + b = true; + break; + } + if (! b) + _f.push_back(_f2[i]); + } + } + + + /** + * How many in niche + */ + unsigned howManyInNicheOf (const std::vector< ObjectiveVector > & _f, const ObjectiveVector & _s, unsigned _size) { + unsigned n=0; + for (unsigned i=0 ; i<_f.size(); i++) { + if (euclidianDistance(_f[i], _s) < (_s.size() / (double) _size)) + n++; + } + return n; + } + + + /** + * Euclidian distance + */ + double euclidianDistance (const ObjectiveVector & _set1, const ObjectiveVector & _to, unsigned _deg = 2) { + double dist=0; + for (unsigned i=0; i<_set1.size(); i++) + dist += pow(fabs(_set1[i] - _to[i]), (int)_deg); + return pow(dist, 1.0 / _deg); + } }; -#endif /*MOEOENTROPYMETRIC_H_ */ +#endif /*MOEOENTROPYMETRIC_H_*/ diff --git a/trunk/paradiseo-moeo/src/metric/moeoMetric.h b/trunk/paradiseo-moeo/src/metric/moeoMetric.h index 8e29440dd..93917daef 100644 --- a/trunk/paradiseo-moeo/src/metric/moeoMetric.h +++ b/trunk/paradiseo-moeo/src/metric/moeoMetric.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // moeoMetric.h -// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006 +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 /* This library... @@ -16,91 +16,58 @@ #include /** - * Base class for performance metrics (also called quality indicators) + * Base class for performance metrics (also known as quality indicators). */ -class moeoMetric:public eoFunctorBase -{ -}; +class moeoMetric : public eoFunctorBase + {}; /** - * Base class for unary metrics + * Base class for unary metrics. */ -template < class A, class R > class moeoUM:public eoUF < A, R >, - public moeoMetric -{ -}; +template < class A, class R > +class moeoUnaryMetric : public eoUF < A, R >, public moeoMetric + {}; /** - * Base class for binary metrics + * Base class for binary metrics. */ -template < class A1, class A2, class R > class moeoBM:public eoBF < A1, A2, R >, - public moeoMetric -{ -}; +template < class A1, class A2, class R > +class moeoBinaryMetric : public eoBF < A1, A2, R >, public moeoMetric + {}; /** - * Base class for unary metrics dedicated to the performance evaluation of a single solution's Pareto fitness + * Base class for unary metrics dedicated to the performance evaluation of a single solution's objective vector. */ -template < class EOT, class R, class EOFitness = typename EOT::Fitness > class moeoSolutionUM:public moeoUM < - const - EOFitness &, - R > -{ -}; +template < class ObjectiveVector, class R > +class moeoSolutionUnaryMetric : public moeoUnaryMetric < const ObjectiveVector &, R > + {}; /** - * Base class for unary metrics dedicated to the performance evaluation of a Pareto set (a vector of Pareto fitnesses) + * Base class for unary metrics dedicated to the performance evaluation of a Pareto set (a vector of objective vectors) */ -template < class EOT, class R, class EOFitness = typename EOT::Fitness > class moeoVectorUM:public moeoUM < - const - std::vector < -EOFitness > &, - R > -{ -}; +template < class ObjectiveVector, class R > +class moeoVectorUnaryMetric : public moeoUnaryMetric < const std::vector < ObjectiveVector > &, R > + {}; /** - * Base class for binary metrics dedicated to the performance comparison between two solutions's Pareto fitnesses + * Base class for binary metrics dedicated to the performance comparison between two solutions's objective vectors. */ -template < class EOT, class R, class EOFitness = typename EOT::Fitness > class moeoSolutionVsSolutionBM:public moeoBM < - const - EOFitness &, const - EOFitness &, - R > -{ -}; +template < class ObjectiveVector, class R > +class moeoSolutionVsSolutionBinaryMetric : public moeoBinaryMetric < const ObjectiveVector &, const ObjectiveVector &, R > + {}; /** - * Base class for binary metrics dedicated to the performance comparison between a Pareto set (a vector of Pareto fitnesses) and a single solution's Pareto fitness + * Base class for binary metrics dedicated to the performance comparison between two Pareto sets (two vectors of objective vectors) */ -template < class EOT, class R, class EOFitness = typename EOT::Fitness > class moeoVectorVsSolutionBM:public moeoBM < - const - std::vector < -EOFitness > &, const - EOFitness &, - R > -{ -}; +template < class ObjectiveVector, class R > +class moeoVectorVsVectorBinaryMetric : public moeoBinaryMetric < const std::vector < ObjectiveVector > &, const std::vector < ObjectiveVector > &, R > + {}; -/** - * Base class for binary metrics dedicated to the performance comparison between two Pareto sets (two vectors of Pareto fitnesses) - */ -template < class EOT, class R, class EOFitness = typename EOT::Fitness > class moeoVectorVsVectorBM:public moeoBM < - const - std::vector < -EOFitness > &, const - std::vector < -EOFitness > &, - R > -{ -}; - - -#endif /*MOEOMETRIC_H_ */ +#endif /*MOEOMETRIC_H_*/ diff --git a/trunk/paradiseo-moeo/src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h b/trunk/paradiseo-moeo/src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h new file mode 100644 index 000000000..be9e6659c --- /dev/null +++ b/trunk/paradiseo-moeo/src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h @@ -0,0 +1,271 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// moeoNormalizedSolutionVsSolutionBinaryMetric.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef MOEONORMALIZEDSOLUTIONVSSOLUTIONBINARYMETRIC_H_ +#define MOEONORMALIZEDSOLUTIONVSSOLUTIONBINARYMETRIC_H_ + +#include +#include + + +/** + * Base class for binary metrics dedicated to the performance comparison between two solutions's objective vectors using normalized values. + * Then, indicator values lie in the interval [-1,1]. + * Note that you have to set the bounds for every objective before using the operator(). + */ +template < class ObjectiveVector, class R > +class moeoNormalizedSolutionVsSolutionBinaryMetric : public moeoSolutionVsSolutionBinaryMetric < ObjectiveVector, R > +{ +public: + + /** + * Default ctr for any moeoNormalizedSolutionVsSolutionBinaryMetric object + */ + moeoNormalizedSolutionVsSolutionBinaryMetric() + { + bounds.resize(ObjectiveVector::Traits::nObjectives()); + } + + + /** + * Sets the lower bound (_min) and the upper bound (_max) for the objective _obj + * _min lower bound + * _max upper bound + * _obj the objective index + */ + void setup(double _min, double _max, unsigned _obj) + { + if (_min == _max) + { + _min -= tiny(); + _max += tiny(); + } + bounds[_obj] = eoRealInterval(_min, _max); + } + + /** + * Sets the lower bound and the upper bound for the objective _obj using a eoRealInterval object + * _realInterval the eoRealInterval object + * _obj the objective index + */ + virtual void setup(eoRealInterval _realInterval, unsigned _obj) + { + bounds[_obj] = _realInterval; + } + + + /** + * Returns a very small value that can be used to avoid extreme cases (where the min bound == the max bound) + */ + static double tiny() + { + return 1e-6; + } + + +protected: + + /** the bounds for every objective (bounds[i] = bounds for the objective i) */ + std::vector < eoRealInterval > bounds; + +}; + + +/** + * Additive epsilon binary metric allowing to compare two objective vectors as proposed in + * Zitzler E., Thiele L., Laumanns M., Fonseca C. M., Grunert da Fonseca V.: + * Performance Assessment of Multiobjective Optimizers: An Analysis and Review. IEEE Transactions on Evolutionary Computation 7(2), pp.117–132 (2003). + */ +template < class ObjectiveVector > +class moeoAdditiveEpsilonBinaryMetric : public moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > +{ +public: + + /** + * Returns the minimal distance by which the objective vector _o1 must be translated in all objectives + * so that it weakly dominates the objective vector _o2 + * @warning don't forget to set the bounds for every objective before the call of this function + * @param _o1 the first objective vector + * @param _o2 the second objective vector + */ + double operator()(const ObjectiveVector & _o1, const ObjectiveVector & _o2) + { + // computation of the epsilon value for the first objective + double result = epsilon(_o1, _o2, 0); + // computation of the epsilon value for the other objectives + double tmp; + for (unsigned i=1; i :: bounds; + + + /** + * Returns the epsilon value by which the objective vector _o1 must be translated in the objective _obj + * so that it dominates the objective vector _o2 + * @param _o1 the first objective vector + * @param _o2 the second objective vector + * @param _obj the index of the objective + */ + double epsilon(const ObjectiveVector & _o1, const ObjectiveVector & _o2, const unsigned _obj) + { + double result; + // if the objective _obj have to be minimized + if (ObjectiveVector::Traits::minimizing(_obj)) + { + // _o1[_obj] - _o2[_obj] + result = ( (_o1[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() ) - ( (_o2[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() ); + } + // if the objective _obj have to be maximized + else + { + // _o2[_obj] - _o1[_obj] + result = ( (_o2[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() ) - ( (_o1[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() ); + } + return result; + } + +}; + + +/** + * Hypervolume binary metric allowing to compare two objective vectors as proposed in + * Zitzler E., Künzli S.: Indicator-Based Selection in Multiobjective Search. In Parallel Problem Solving from Nature (PPSN VIII). + * Lecture Notes in Computer Science 3242, Springer, Birmingham, UK pp.832–842 (2004). + * This indicator is based on the hypervolume concept introduced in + * Zitzler, E., Thiele, L.: Multiobjective Optimization Using Evolutionary Algorithms - A Comparative Case Study. + * Parallel Problem Solving from Nature (PPSN-V), pp.292-301 (1998). + */ +template < class ObjectiveVector > +class moeoHypervolumeBinaryMetric : public moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > +{ +public: + + /** + * Ctor + * @param _rho value used to compute the reference point from the worst values for each objective (default : 1.1) + */ + moeoHypervolumeBinaryMetric(double _rho = 1.1) : rho(_rho) + { + // not-a-maximization problem check + for (unsigned i=0; i :: bounds; + /** Functor to compare two objective vectors according to Pareto dominance relation */ + moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator; + + /** + * Returns the volume of the space that is dominated by _o2 but not by _o1 with respect to a reference point computed using rho for the objective _obj. + * @param _o1 the first objective vector + * @param _o2 the second objective vector + * @param _obj the objective index + * @param _flag used for iteration, if _flag=true _o2 is not talen into account (default : false) + */ + double hypervolume(const ObjectiveVector & _o1, const ObjectiveVector & _o2, const unsigned _obj, const bool _flag = false) + { + double result; + double range = rho * bounds[_obj].range(); + double max = bounds[_obj].minimum() + range; + // value of _1 for the objective _obj + double v1 = _o1[_obj]; + // value of _2 for the objective _obj (if _flag=true, v2=max) + double v2; + if (_flag) + { + v2 = max; + } + else + { + v2 = _o2[_obj]; + } + // computation of the volume + if (_obj == 0) + { + if (v1 < v2) + { + result = (v2 - v1) / range; + } + else + { + result = 0; + } + } + else + { + if (v1 < v2) + { + result = ( hypervolume(_o1, _o2, _obj-1, true) * (v2 - v1) / range ) + ( hypervolume(_o1, _o2, _obj-1) * (max - v2) / range ); + } + else + { + result = hypervolume(_o1, _o2, _obj-1) * (max - v2) / range; + } + } + return result; + } + +}; + + +#endif /*MOEONORMALIZEDSOLUTIONVSSOLUTIONBINARYMETRIC_H_*/