moeoEntropyMetric.h

00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // moeoEntropyMetric.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 MOEOENTROPYMETRIC_H_
00014 #define MOEOENTROPYMETRIC_H_
00015 
00016 #include <metric/moeoMetric.h>
00017 
00023 template < class EOT > class moeoEntropyMetric:public moeoVectorVsVectorBM < EOT,
00024   double >
00025 {
00026 public:
00027 
00031   typedef typename EOT::Fitness EOFitness;
00032 
00038   double operator () (const std::vector < EOFitness > &_set1,
00039                       const std::vector < EOFitness > &_set2)
00040   {
00041     // normalization
00042     std::vector < EOFitness > set1 = _set1;
00043     std::vector < EOFitness > set2 = _set2;
00044     removeDominated (set1);
00045     removeDominated (set2);
00046     prenormalize (set1);
00047     normalize (set1);
00048     normalize (set2);
00049 
00050     // making of PO*
00051     std::vector < EOFitness > star;     // rotf :-)
00052     computeUnion (set1, set2, star);
00053     removeDominated (star);
00054 
00055     // making of PO1 U PO*
00056     std::vector < EOFitness > union_set1_star;  // rotf again ...
00057     computeUnion (set1, star, union_set1_star);
00058 
00059     unsigned C = union_set1_star.size ();
00060     float omega = 0;
00061     float entropy = 0;
00062 
00063     for (unsigned i = 0; i < C; i++)
00064       {
00065         unsigned N_i =
00066           howManyInNicheOf (union_set1_star, union_set1_star[i],
00067                             star.size ());
00068         unsigned n_i =
00069           howManyInNicheOf (set1, union_set1_star[i], star.size ());
00070         if (n_i > 0)
00071           {
00072             omega += 1.0 / N_i;
00073             entropy +=
00074               (float) n_i / (N_i * C) * log (((float) n_i / C) / log (2.0));
00075           }
00076       }
00077     entropy /= -log (omega);
00078     entropy *= log (2.0);
00079     return entropy;
00080   }
00081 
00082 
00083 private:
00084 
00085   std::vector < double >vect_min_val;
00086   std::vector < double >vect_max_val;
00087 
00088   void removeDominated (std::vector < EOFitness > &_f)
00089   {
00090     for (unsigned i = 0; i < _f.size (); i++)
00091       {
00092         bool dom = false;
00093         for (unsigned j = 0; j < _f.size (); j++)
00094           if (i != j && _f[j].dominates (_f[i]))
00095             {
00096               dom = true;
00097               break;
00098             }
00099         if (dom)
00100           {
00101             _f[i] = _f.back ();
00102             _f.pop_back ();
00103             i--;
00104           }
00105       }
00106   }
00107 
00108   void prenormalize (const std::vector < EOFitness > &_f)
00109   {
00110     vect_min_val.clear ();
00111     vect_max_val.clear ();
00112 
00113     for (unsigned char i = 0; i < EOFitness::fitness_traits::nObjectives ();
00114          i++)
00115       {
00116         float min_val = _f.front ()[i], max_val = min_val;
00117         for (unsigned j = 1; j < _f.size (); j++)
00118           {
00119             if (_f[j][i] < min_val)
00120               min_val = _f[j][i];
00121             if (_f[j][i] > max_val)
00122               max_val = _f[j][i];
00123           }
00124         vect_min_val.push_back (min_val);
00125         vect_max_val.push_back (max_val);
00126       }
00127   }
00128 
00129   void normalize (std::vector < EOFitness > &_f)
00130   {
00131     for (unsigned i = 0; i < EOFitness::fitness_traits::nObjectives (); i++)
00132       for (unsigned j = 0; j < _f.size (); j++)
00133         _f[j][i] =
00134           (_f[j][i] - vect_min_val[i]) / (vect_max_val[i] - vect_min_val[i]);
00135   }
00136 
00137   void computeUnion (const std::vector < EOFitness > &_f1,
00138                      const std::vector < EOFitness > &_f2,
00139                      std::vector < EOFitness > &_f)
00140   {
00141     _f = _f1;
00142     for (unsigned i = 0; i < _f2.size (); i++)
00143       {
00144         bool b = false;
00145         for (unsigned j = 0; j < _f1.size (); j++)
00146           if (_f1[j] == _f2[i])
00147             {
00148               b = true;
00149               break;
00150             }
00151         if (!b)
00152           _f.push_back (_f2[i]);
00153       }
00154   }
00155 
00156   unsigned howManyInNicheOf (const std::vector < EOFitness > &_f,
00157                              const EOFitness & _s, unsigned _size)
00158   {
00159     unsigned n = 0;
00160     for (unsigned i = 0; i < _f.size (); i++)
00161       {
00162         if (euclidianDistance (_f[i], _s) < (_s.size () / (double) _size))
00163           n++;
00164       }
00165     return n;
00166   }
00167 
00168   double euclidianDistance (const EOFitness & _set1, const EOFitness & _to,
00169                             unsigned _deg = 2)
00170   {
00171     double dist = 0;
00172     for (unsigned i = 0; i < _set1.size (); i++)
00173       dist += pow (fabs (_set1[i] - _to[i]), (int) _deg);
00174     return pow (dist, 1.0 / _deg);
00175   }
00176 
00177 };
00178 
00179 #endif /*MOEOENTROPYMETRIC_H_ */

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