- Main Page
- Classes
- Files

- Search for |

# moeoBinaryQualityIndicator.h

    00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
    00002
    00003 //-----------------------------------------------------------------------------
    00004 // moeoBinaryQualityIndicator.h
    00005 // (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2006
    00006 /*
    00007     This library...
    00008
    00009     Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
    00010  */
    00011 //-----------------------------------------------------------------------------
    00012
    00013 #ifndef _moeoBinaryQualityIndicator_h
    00014 #define _moeoBinaryQualityIndicator_h
    00015
    00016 // for std::exceptions
    00017 #include <stdexcept>
    00018 // for eoBF
    00019 #include <eoFunctor.h>
    00020
    00021
    00028 template < class EOFitness > class moeoBinaryQualityIndicator:public eoBF < const EOFitness &, const EOFitness &,
    00029   double >
    00030 {
    00031
    00032 public:
    00033
    00037   moeoBinaryQualityIndicator ():eoBF < const EOFitness &, const EOFitness &,
    00038     double >()
    00039   {
    00040     bounds.reserve (traits::nObjectives ());
    00041     bounds.resize (traits::nObjectives ());
    00042   }
    00043
    00044
    00051   void setBounds (const unsigned _iObj, const double _min, const double _max)
    00052   {
    00053     bounds[_iObj] = Range (_min, _max);
    00054   }
    00055
    00056
    00057 protected:
    00058
    00062   class Range
    00063   {
    00064   public:
    00065     Range ()
    00066     {
    00067       min = 0;
    00068       max = 0;
    00069       r = 0;
    00070     }
    00071     Range (const double _min, const double _max)
    00072     {
    00073       min = _min;
    00074       max = _max;
    00075       r = max - min;
    00076       if (r < 0)
    00077         throw std::logic_error ("Negative range in eoBinaryQualityIndicator");
    00078     }
    00079     double minimum ()
    00080     {
    00081       return min;
    00082     }
    00083     double maximum ()
    00084     {
    00085       return max;
    00086     }
    00087     double range ()
    00088     {
    00089       return r;
    00090     }
    00091   private:
    00092     double min, max, r;
    00093   };
    00094
    00095
    00097   std::vector < Range > bounds;
    00098
    00099
    00100 private:
    00101
    00103   typedef typename EOFitness::fitness_traits traits;
    00104
    00105 };
    00106
    00107
    00108
    00109
    00110
    00115 template < class EOFitness > class moeoAdditiveBinaryEpsilonIndicator:public moeoBinaryQualityIndicator <
    00116   EOFitness
    00117   >
    00118 {
    00119
    00120 public:
    00121
    00125 moeoAdditiveBinaryEpsilonIndicator ():moeoBinaryQualityIndicator < EOFitness >
    00126     ()
    00127   {
    00128   }
    00129
    00130
    00138   double operator  () (const EOFitness & _fitness_eo1,
    00139                        const EOFitness & _fitness_eo2)
    00140   {
    00141     double epsilon, tmp;
    00142     // computation of the epsilon value for the first objective
    00143     epsilon = epsilonValue (_fitness_eo1, _fitness_eo2, 0);
    00144     // computation of the epsilon value for other objectives
    00145     for (unsigned i = 1; i < traits::nObjectives (); i++)
    00146       {
    00147         tmp = epsilonValue (_fitness_eo1, _fitness_eo2, i);
    00148         epsilon = std::max (epsilon, tmp);
    00149       }
    00150     // the maximum epsilon value
    00151     return epsilon;
    00152   }
    00153
    00154
    00155 private:
    00156
    00158   typedef typename EOFitness::fitness_traits traits;
    00160   using moeoBinaryQualityIndicator < EOFitness >::bounds;
    00161
    00162
    00170   double epsilonValue (const EOFitness & _fitness_eo1,
    00171                        const EOFitness & _fitness_eo2, const unsigned _iObj)
    00172   {
    00173     double result;
    00174     if (bounds[_iObj].range () == 0)
    00175       {
    00176         // min==max => every individuals has the same value for this objective
    00177         result = 0;
    00178       }
    00179     else
    00180       {
    00181         // computation of the epsilon value for the objective _iObj (in case of a minimization)
    00182         result =
    00183           (_fitness_eo1[_iObj] -
    00184            bounds[_iObj].minimum ()) / bounds[_iObj].range ();
    00185         result -=
    00186           (_fitness_eo2[_iObj] -
    00187            bounds[_iObj].minimum ()) / bounds[_iObj].range ();
    00188         // if we are maximizing, invert the value
    00189         if (traits::maximizing (_iObj))
    00190           result = -result;
    00191       }
    00192     // the espilon value
    00193     return result;
    00194   }
    00195
    00196 };
    00197
    00198
    00199
    00200
    00201
    00206 template < class EOFitness > class moeoBinaryHypervolumeIndicator:public moeoBinaryQualityIndicator <
    00207   EOFitness >
    00208 {
    00209
    00210 public:
    00211
    00216 moeoBinaryHypervolumeIndicator (double _rho):moeoBinaryQualityIndicator < EOFitness >
    00217     ()
    00218   {
    00219     rho = _rho;
    00220     // consistency check
    00221     if (rho < 1)
    00222       {
    00223         cout <<
    00224           "Warning, reference point rho for the hypervolume calculation must not be smaller than 1"
    00225           << endl;
    00226         cout << "Adjusted to 1" << endl;
    00227         rho = 1;
    00228       }
    00229   }
    00230
    00231
    00239   double operator  () (const EOFitness & _fitness_eo1,
    00240                        const EOFitness & _fitness_eo2)
    00241   {
    00242     double result;
    00243     if (_fitness_eo1.dominates (_fitness_eo2))
    00244       result =
    00245         -hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
    00246                                     traits::nObjectives ());
    00247     else
    00248       result =
    00249         hypervolumeIndicatorValue (_fitness_eo2, _fitness_eo1,
    00250                                    traits::nObjectives ());
    00251     return result;
    00252   }
    00253
    00254
    00255 private:
    00256
    00258   typedef typename EOFitness::fitness_traits traits;
    00260   using moeoBinaryQualityIndicator < EOFitness >::bounds;
    00261
    00263   double rho;
    00264
    00265
    00274   double hypervolumeIndicatorValue (const EOFitness & _fitness_eo1,
    00275                                     const EOFitness & _fitness_eo2,
    00276                                     const unsigned _iObj, const bool _flag =
    00277                                     false)
    00278   {
    00279     double result;
    00280     if (bounds[_iObj - 1].range () == 0)
    00281       {
    00282         // min==max => every individuals as the same value for this objective
    00283         result = 0;
    00284       }
    00285     else
    00286       {
    00287         if (traits::maximizing (_iObj - 1))     // maximizing
    00288           result =
    00289             hypervolumeIndicatorValueMax (_fitness_eo1, _fitness_eo2, _iObj,
    00290                                           _flag);
    00291         else                    // minimizing
    00292           result =
    00293             hypervolumeIndicatorValueMin (_fitness_eo1, _fitness_eo2, _iObj,
    00294                                           _flag);
    00295       }
    00296     return result;
    00297   }
    00298
    00299
    00309   double hypervolumeIndicatorValueMin (const EOFitness & _fitness_eo1,
    00310                                        const EOFitness & _fitness_eo2,
    00311                                        const unsigned _iObj, const bool _flag)
    00312   {
    00313     double result;
    00314     double r = rho * bounds[_iObj - 1].range ();
    00315     double max = bounds[_iObj - 1].minimum () + r;
    00316     // fitness of individuals _eo1 and _eo2 for the objective _iObj (if flag==true, _eo2 is not taken into account)
    00317     double fitness_eo1 = _fitness_eo1[_iObj - 1];
    00318     double fitness_eo2;
    00319     if (_flag)
    00320       fitness_eo2 = max;
    00321     else
    00322       fitness_eo2 = _fitness_eo2[_iObj - 1];
    00323     // computation of the volume
    00324     if (_iObj == 1)
    00325       {
    00326         if (fitness_eo1 < fitness_eo2)
    00327           result = (fitness_eo2 - fitness_eo1) / r;
    00328         else
    00329           result = 0;
    00330       }
    00331     else
    00332       {
    00333         if (fitness_eo1 < fitness_eo2)
    00334           {
    00335             result =
    00336               hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
    00337                                          _iObj - 1) * (max - fitness_eo2) / r;
    00338             result +=
    00339               hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
    00340                                          _iObj - 1,
    00341                                          true) * (fitness_eo2 -
    00342                                                   fitness_eo1) / r;
    00343           }
    00344         else
    00345           result =
    00346             hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
    00347                                        _iObj - 1) * (max - fitness_eo2) / r;
    00348       }
    00349     // the volume
    00350     return result;
    00351   }
    00352
    00353
    00363   double hypervolumeIndicatorValueMax (const EOFitness & _fitness_eo1,
    00364                                        const EOFitness & _fitness_eo2,
    00365                                        const unsigned _iObj, const bool _flag)
    00366   {
    00367     double result;
    00368     double r = rho * bounds[_iObj - 1].range ();
    00369     double min = bounds[_iObj - 1].maximum () - r;
    00370     // fitness of individuals _eo1 and _eo2 for the objective _iObj (if flag==true, _eo2 is not taken into account)
    00371     double fitness_eo1 = _fitness_eo1[_iObj - 1];
    00372     double fitness_eo2;
    00373     if (_flag)
    00374       fitness_eo2 = min;
    00375     else
    00376       fitness_eo2 = _fitness_eo2[_iObj - 1];
    00377     // computation of the volume
    00378     if (_iObj == 1)
    00379       {
    00380         if (fitness_eo1 > fitness_eo2)
    00381           result = (fitness_eo1 - fitness_eo2) / r;
    00382         else
    00383           result = 0;
    00384       }
    00385     else
    00386       {
    00387         if (fitness_eo1 > fitness_eo2)
    00388           {
    00389             result =
    00390               hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
    00391                                          _iObj - 1) * (fitness_eo2 - min) / r;
    00392             result +=
    00393               hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
    00394                                          _iObj - 1,
    00395                                          true) * (fitness_eo1 -
    00396                                                   fitness_eo2) / r;
    00397           }
    00398         else
    00399           result =
    00400             hypervolumeIndicatorValue (_fitness_eo1, _fitness_eo2,
    00401                                        _iObj - 1) * (fitness_eo2 - min) / r;
    00402       }
    00403     // the volume
    00404     return result;
    00405   }
    00406
    00407 };
    00408
    00409 #endif