00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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
00051 std::vector < EOFitness > star;
00052 computeUnion (set1, set2, star);
00053 removeDominated (star);
00054
00055
00056 std::vector < EOFitness > union_set1_star;
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