00001 #include <limits>
00002 #include <moo/eoNSGA_II_Eval.h>
00003
00004 namespace nsga2 {
00005
00006 using namespace std;
00007
00008 typedef std::pair<double, unsigned> double_index_pair;
00009
00010 class compare_nodes
00011 {
00012 public :
00013 bool operator()(const double_index_pair& a, const double_index_pair& b) const
00014 {
00015 return a.first < b.first;
00016 }
00017 };
00018
00019 void assign_worths(const std::vector<detail::FitnessInfo>& front, unsigned rank, std::vector<double>& worths) {
00020
00021 unsigned nObjectives = front[0].fitness.size();
00022
00023 std::vector<double> niche_distance(front.size());
00024
00025 for (unsigned o = 0; o < nObjectives; ++o)
00026 {
00027
00028 std::vector<std::pair<double, unsigned> > performance(front.size());
00029 for (unsigned i =0; i < front.size(); ++i)
00030 {
00031 performance[i].first = front[i].fitness[o];
00032 performance[i].second = i;
00033 }
00034
00035 std::sort(performance.begin(), performance.end(), compare_nodes());
00036
00037 std::vector<double> nc(front.size(), 0.0);
00038
00039 for (unsigned i = 1; i < front.size()-1; ++i)
00040 {
00041
00042 nc[performance[i].second] = performance[i+1].first - performance[i-1].first;
00043
00044 }
00045
00046
00047
00048 nc[performance.back().second] = std::numeric_limits<double>::infinity();
00049
00050 for (unsigned i = 0; i < nc.size(); ++i)
00051 {
00052 niche_distance[i] += nc[i];
00053 }
00054 }
00055
00056
00057
00058 double max = 0;
00059 for (unsigned i = 0; i < niche_distance.size(); ++i) {
00060 if (niche_distance[i] != std::numeric_limits<double>::infinity()) {
00061 max = std::max(max, niche_distance[i]);
00062 }
00063 }
00064
00065 for (unsigned i = 0; i < front.size(); ++i) {
00066 double dist = niche_distance[i];
00067 if (dist == std::numeric_limits<double>::infinity()) {
00068 dist = 1.0;
00069 } else {
00070 dist /= (1+max);
00071 }
00072
00073 unsigned idx = front[i].index;
00074
00075 worths[idx] = rank + dist;
00076 }
00077
00078 }
00079
00080 }