00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef MOEOENTROPYMETRIC_H_
00014 #define MOEOENTROPYMETRIC_H_
00015
00016 #include <vector>
00017 #include <comparator/moeoParetoObjectiveVectorComparator.h>
00018 #include <metric/moeoMetric.h>
00019
00024 template < class ObjectiveVector >
00025 class moeoEntropyMetric : public moeoVectorVsVectorBinaryMetric < ObjectiveVector, double >
00026 {
00027 public:
00028
00034 double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
00035
00036 std::vector< ObjectiveVector > set1 = _set1;
00037 std::vector< ObjectiveVector > set2= _set2;
00038 removeDominated (set1);
00039 removeDominated (set2);
00040 prenormalize (set1);
00041 normalize (set1);
00042 normalize (set2);
00043
00044
00045 std::vector< ObjectiveVector > star;
00046 computeUnion (set1, set2, star);
00047 removeDominated (star);
00048
00049
00050 std::vector< ObjectiveVector > union_set1_star;
00051 computeUnion (set1, star, union_set1_star);
00052
00053 unsigned int C = union_set1_star.size();
00054 float omega=0;
00055 float entropy=0;
00056
00057 for (unsigned int i=0 ; i<C ; i++) {
00058 unsigned int N_i = howManyInNicheOf (union_set1_star, union_set1_star[i], star.size());
00059 unsigned int n_i = howManyInNicheOf (set1, union_set1_star[i], star.size());
00060 if (n_i > 0) {
00061 omega += 1.0 / N_i;
00062 entropy += (float) n_i / (N_i * C) * log (((float) n_i / C) / log (2.0));
00063 }
00064 }
00065 entropy /= - log (omega);
00066 entropy *= log (2.0);
00067 return entropy;
00068 }
00069
00070
00071 private:
00072
00074 std::vector<double> vect_min_val;
00076 std::vector<double> vect_max_val;
00078 moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator;
00079
00080
00085 void removeDominated(std::vector < ObjectiveVector > & _f) {
00086 for (unsigned int i=0 ; i<_f.size(); i++) {
00087 bool dom = false;
00088 for (unsigned int j=0; j<_f.size(); j++)
00089 if (i != j && paretoComparator(_f[i],_f[j]))
00090 {
00091 dom = true;
00092 break;
00093 }
00094 if (dom) {
00095 _f[i] = _f.back();
00096 _f.pop_back();
00097 i--;
00098 }
00099 }
00100 }
00101
00102
00107 void prenormalize (const std::vector< ObjectiveVector > & _f) {
00108 vect_min_val.clear();
00109 vect_max_val.clear();
00110
00111 for (unsigned int i=0 ; i<ObjectiveVector::nObjectives(); i++) {
00112 float min_val = _f.front()[i], max_val = min_val;
00113 for (unsigned int j=1 ; j<_f.size(); j++) {
00114 if (_f[j][i] < min_val)
00115 min_val = _f[j][i];
00116 if (_f[j][i]>max_val)
00117 max_val = _f[j][i];
00118 }
00119 vect_min_val.push_back(min_val);
00120 vect_max_val.push_back (max_val);
00121 }
00122 }
00123
00124
00129 void normalize (std::vector< ObjectiveVector > & _f) {
00130 for (unsigned int i=0 ; i<ObjectiveVector::nObjectives(); i++)
00131 for (unsigned int j=0; j<_f.size(); j++)
00132 _f[j][i] = (_f[j][i] - vect_min_val[i]) / (vect_max_val[i] - vect_min_val[i]);
00133 }
00134
00135
00142 void computeUnion(const std::vector< ObjectiveVector > & _f1, const std::vector< ObjectiveVector > & _f2, std::vector< ObjectiveVector > & _f) {
00143 _f = _f1 ;
00144 for (unsigned int i=0; i<_f2.size(); i++) {
00145 bool b = false;
00146 for (unsigned int j=0; j<_f1.size(); j ++)
00147 if (_f1[j] == _f2[i]) {
00148 b = true;
00149 break;
00150 }
00151 if (! b)
00152 _f.push_back(_f2[i]);
00153 }
00154 }
00155
00156
00160 unsigned int howManyInNicheOf (const std::vector< ObjectiveVector > & _f, const ObjectiveVector & _s, unsigned int _size) {
00161 unsigned int n=0;
00162 for (unsigned int i=0 ; i<_f.size(); i++) {
00163 if (euclidianDistance(_f[i], _s) < (_s.size() / (double) _size))
00164 n++;
00165 }
00166 return n;
00167 }
00168
00169
00173 double euclidianDistance (const ObjectiveVector & _set1, const ObjectiveVector & _to, unsigned int _deg = 2) {
00174 double dist=0;
00175 for (unsigned int i=0; i<_set1.size(); i++)
00176 dist += pow(fabs(_set1[i] - _to[i]), (int)_deg);
00177 return pow(dist, 1.0 / _deg);
00178 }
00179
00180 };
00181
00182 #endif