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 = howManyInNicheOf (union_set1_star, union_set1_star[i],
00066                                          star.size ());
00067         unsigned n_i =
00068           howManyInNicheOf (set1, union_set1_star[i], star.size ());
00069         if (n_i > 0)
00070           {
00071             omega += 1.0 / N_i;
00072             entropy +=
00073               (float) n_i / (N_i * C) * log (((float) n_i / C) / log (2.0));
00074           }
00075       }
00076     entropy /= -log (omega);
00077     entropy *= log (2.0);
00078     return entropy;
00079   }
00080 
00081 
00082 private:
00083 
00084   std::vector < double >vect_min_val;
00085   std::vector < double >vect_max_val;
00086 
00087   void removeDominated (std::vector < EOFitness > &_f)
00088   {
00089     for (unsigned i = 0; i < _f.size (); i++)
00090       {
00091         bool dom = false;
00092         for (unsigned j = 0; j < _f.size (); j++)
00093           if (i != j && _f[j].dominates (_f[i]))
00094             {
00095               dom = true;
00096               break;
00097             }
00098         if (dom)
00099           {
00100             _f[i] = _f.back ();
00101             _f.pop_back ();
00102             i--;
00103           }
00104       }
00105   }
00106 
00107   void prenormalize (const std::vector < EOFitness > &_f)
00108   {
00109     vect_min_val.clear ();
00110     vect_max_val.clear ();
00111 
00112     for (unsigned char i = 0; i < EOFitness::fitness_traits::nObjectives ();
00113          i++)
00114       {
00115         float min_val = _f.front ()[i], max_val = min_val;
00116         for (unsigned j = 1; j < _f.size (); j++)
00117           {
00118             if (_f[j][i] < min_val)
00119               min_val = _f[j][i];
00120             if (_f[j][i] > max_val)
00121               max_val = _f[j][i];
00122           }
00123         vect_min_val.push_back (min_val);
00124         vect_max_val.push_back (max_val);
00125       }
00126   }
00127 
00128   void normalize (std::vector < EOFitness > &_f)
00129   {
00130     for (unsigned i = 0; i < EOFitness::fitness_traits::nObjectives (); i++)
00131       for (unsigned j = 0; j < _f.size (); j++)
00132         _f[j][i] =
00133           (_f[j][i] - vect_min_val[i]) / (vect_max_val[i] - vect_min_val[i]);
00134   }
00135 
00136   void computeUnion (const std::vector < EOFitness > &_f1,
00137                      const std::vector < EOFitness > &_f2,
00138                      std::vector < EOFitness > &_f)
00139   {
00140     _f = _f1;
00141     for (unsigned i = 0; i < _f2.size (); i++)
00142       {
00143         bool b = false;
00144         for (unsigned j = 0; j < _f1.size (); j++)
00145           if (_f1[j] == _f2[i])
00146             {
00147               b = true;
00148               break;
00149             }
00150         if (!b)
00151           _f.push_back (_f2[i]);
00152       }
00153   }
00154 
00155   unsigned howManyInNicheOf (const std::vector < EOFitness > &_f,
00156                              const EOFitness & _s, unsigned _size)
00157   {
00158     unsigned n = 0;
00159     for (unsigned i = 0; i < _f.size (); i++)
00160       {
00161         if (euclidianDistance (_f[i], _s) < (_s.size () / (double) _size))
00162           n++;
00163       }
00164     return n;
00165   }
00166 
00167   double euclidianDistance (const EOFitness & _set1, const EOFitness & _to,
00168                             unsigned _deg = 2)
00169   {
00170     double dist = 0;
00171     for (unsigned i = 0; i < _set1.size (); i++)
00172       dist += pow (fabs (_set1[i] - _to[i]), (int) _deg);
00173     return pow (dist, 1.0 / _deg);
00174   }
00175 
00176 };
00177 
00178 #endif /*MOEOENTROPYMETRIC_H_ */

Generated on Wed Dec 6 10:16:12 2006 for ParadisEO-MOEO by  doxygen 1.5.1