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 =
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