00001 #ifndef __eoNSGA_I_Eval_h_
00002 #define __eoNSGA_I_Eval_h_
00003
00004 #include <moo/eoFrontSorter.h>
00005 #include <moo/eoMOEval.h>
00006
00010 template <class EOT>
00011 class eoNSGA_I_Eval : public eoMOEval<EOT>
00012 {
00013 public :
00014 eoNSGA_I_Eval(double nicheWidth, eoEvalFunc<EOT>& eval) : eoMOEval<EOT>(eval), nicheSize(nicheWidth) {}
00015 eoNSGA_I_Eval(double nicheWidth, eoPopEvalFunc<EOT>& eval) : eoMOEval<EOT>(eval), nicheSize(nicheWidth) {}
00016
00017 virtual void operator()(eoPop<EOT>& parents, eoPop<EOT>& offspring) {
00018 eval(parents, offspring);
00019
00020 std::vector<EOT*> pop;
00021 pop.reserve(parents.size() + offspring.size());
00022 for (unsigned i = 0; i < parents.size(); ++i) pop.push_back(&parents[i]);
00023 for (unsigned i = 0; i < offspring.size(); ++i) pop.push_back(&offspring[i]);
00024
00025 typename eoFrontSorter<EOT>::front_t front = sorter(pop);
00026
00027 for (unsigned i = 0; i < front.size(); ++i) {
00028 assign_worths(front[i], front.size() - i, pop);
00029 }
00030 }
00031
00032 private:
00033 void assign_worths(const std::vector<detail::FitnessInfo>& front, unsigned rank, std::vector<EOT*>& parents) {
00034
00035 for (unsigned i = 0; i < front.size(); ++i)
00036 {
00037 double niche_count = 0;
00038
00039 for (unsigned j = 0; j < front.size(); ++j)
00040 {
00041 if (i == j)
00042 continue;
00043
00044 double dist = 0.0;
00045
00046 for (unsigned k = 0; k < front[j].fitness.size(); ++k)
00047 {
00048 double d = front[i].fitness[k] - front[j].fitness[k];
00049 dist += d*d;
00050 }
00051
00052 if (dist < nicheSize)
00053 {
00054 niche_count += 1.0 - pow(dist / nicheSize,2.);
00055 }
00056 }
00057
00058 unsigned idx = front[i].index;
00059 typename EOT::Fitness f = parents[idx]->fitness();
00060 f.setWorth(rank + niche_count);
00061 parents[ idx ]->fitness(f);
00062 }
00063 }
00064
00065 private :
00066
00067 double nicheSize;
00068 eoFrontSorter<EOT> sorter;
00069 };
00070
00071 #endif
00072
00073