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

Generated on Tue Jan 16 15:49:53 2007 for ParadisEO-MOEO by  doxygen 1.5.1