00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef MOEOENTROPYMETRIC_H_
00039 #define MOEOENTROPYMETRIC_H_
00040
00041 #include <vector>
00042 #include <comparator/moeoParetoObjectiveVectorComparator.h>
00043 #include <metric/moeoMetric.h>
00044
00049 template < class ObjectiveVector >
00050 class moeoEntropyMetric : public moeoVectorVsVectorBinaryMetric < ObjectiveVector, double >
00051 {
00052 public:
00053
00059 double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
00060
00061 std::vector< ObjectiveVector > set1 = _set1;
00062 std::vector< ObjectiveVector > set2= _set2;
00063 removeDominated (set1);
00064 removeDominated (set2);
00065 prenormalize (set1);
00066 normalize (set1);
00067 normalize (set2);
00068
00069
00070 std::vector< ObjectiveVector > star;
00071 computeUnion (set1, set2, star);
00072 removeDominated (star);
00073
00074
00075 std::vector< ObjectiveVector > union_set1_star;
00076 computeUnion (set1, star, union_set1_star);
00077
00078 unsigned int C = union_set1_star.size();
00079 float omega=0;
00080 float entropy=0;
00081
00082 for (unsigned int i=0 ; i<C ; i++) {
00083 unsigned int N_i = howManyInNicheOf (union_set1_star, union_set1_star[i], star.size());
00084 unsigned int n_i = howManyInNicheOf (set1, union_set1_star[i], star.size());
00085 if (n_i > 0) {
00086 omega += 1.0 / N_i;
00087 entropy += (float) n_i / (N_i * C) * log (((float) n_i / C) / log (2.0));
00088 }
00089 }
00090 entropy /= - log (omega);
00091 entropy *= log (2.0);
00092 return entropy;
00093 }
00094
00095
00096 private:
00097
00099 std::vector<double> vect_min_val;
00101 std::vector<double> vect_max_val;
00103 moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator;
00104
00105
00110 void removeDominated(std::vector < ObjectiveVector > & _f) {
00111 for (unsigned int i=0 ; i<_f.size(); i++) {
00112 bool dom = false;
00113 for (unsigned int j=0; j<_f.size(); j++)
00114 if (i != j && paretoComparator(_f[i],_f[j]))
00115 {
00116 dom = true;
00117 break;
00118 }
00119 if (dom) {
00120 _f[i] = _f.back();
00121 _f.pop_back();
00122 i--;
00123 }
00124 }
00125 }
00126
00127
00132 void prenormalize (const std::vector< ObjectiveVector > & _f) {
00133 vect_min_val.clear();
00134 vect_max_val.clear();
00135
00136 for (unsigned int i=0 ; i<ObjectiveVector::nObjectives(); i++) {
00137 float min_val = _f.front()[i], max_val = min_val;
00138 for (unsigned int j=1 ; j<_f.size(); j++) {
00139 if (_f[j][i] < min_val)
00140 min_val = _f[j][i];
00141 if (_f[j][i]>max_val)
00142 max_val = _f[j][i];
00143 }
00144 vect_min_val.push_back(min_val);
00145 vect_max_val.push_back (max_val);
00146 }
00147 }
00148
00149
00154 void normalize (std::vector< ObjectiveVector > & _f) {
00155 for (unsigned int i=0 ; i<ObjectiveVector::nObjectives(); i++)
00156 for (unsigned int j=0; j<_f.size(); j++)
00157 _f[j][i] = (_f[j][i] - vect_min_val[i]) / (vect_max_val[i] - vect_min_val[i]);
00158 }
00159
00160
00167 void computeUnion(const std::vector< ObjectiveVector > & _f1, const std::vector< ObjectiveVector > & _f2, std::vector< ObjectiveVector > & _f) {
00168 _f = _f1 ;
00169 for (unsigned int i=0; i<_f2.size(); i++) {
00170 bool b = false;
00171 for (unsigned int j=0; j<_f1.size(); j ++)
00172 if (_f1[j] == _f2[i]) {
00173 b = true;
00174 break;
00175 }
00176 if (! b)
00177 _f.push_back(_f2[i]);
00178 }
00179 }
00180
00181
00185 unsigned int howManyInNicheOf (const std::vector< ObjectiveVector > & _f, const ObjectiveVector & _s, unsigned int _size) {
00186 unsigned int n=0;
00187 for (unsigned int i=0 ; i<_f.size(); i++) {
00188 if (euclidianDistance(_f[i], _s) < (_s.size() / (double) _size))
00189 n++;
00190 }
00191 return n;
00192 }
00193
00194
00198 double euclidianDistance (const ObjectiveVector & _set1, const ObjectiveVector & _to, unsigned int _deg = 2) {
00199 double dist=0;
00200 for (unsigned int i=0; i<_set1.size(); i++)
00201 dist += pow(fabs(_set1[i] - _to[i]), (int)_deg);
00202 return pow(dist, 1.0 / _deg);
00203 }
00204
00205 };
00206
00207 #endif