moeoFastNonDominatedSortingFitnessAssignment.h

00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // moeoFastNonDominatedSortingFitnessAssignment.h
00005 // (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007
00006 /*
00007     This library...
00008 
00009     Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr
00010  */
00011 //-----------------------------------------------------------------------------
00012 
00013 #ifndef MOEOFASTNONDOMINATEDSORTINGFITNESSASSIGNMENT_H_
00014 #define MOEOFASTNONDOMINATEDSORTINGFITNESSASSIGNMENT_H_
00015 
00016 #include <vector>
00017 #include <eoPop.h>
00018 #include <comparator/moeoObjectiveObjectiveVectorComparator.h>
00019 #include <comparator/moeoObjectiveVectorComparator.h>
00020 #include <comparator/moeoParetoObjectiveVectorComparator.h>
00021 #include <fitness/moeoParetoBasedFitnessAssignment.h>
00022 
00023 
00031 template < class MOEOT >
00032 class moeoFastNonDominatedSortingFitnessAssignment : public moeoParetoBasedFitnessAssignment < MOEOT >
00033 {
00034 public:
00035 
00037     typedef typename MOEOT::ObjectiveVector ObjectiveVector;
00038 
00039 
00043     moeoFastNonDominatedSortingFitnessAssignment() : comparator(paretoComparator)
00044     {}
00045 
00046 
00051     moeoFastNonDominatedSortingFitnessAssignment(moeoObjectiveVectorComparator < ObjectiveVector > & _comparator) : comparator(_comparator)
00052     {}
00053 
00054 
00059     void operator()(eoPop < MOEOT > & _pop)
00060     {
00061         // number of objectives for the problem under consideration
00062         unsigned int nObjectives = MOEOT::ObjectiveVector::nObjectives();
00063         if (nObjectives == 1)
00064         {
00065             // one objective
00066             oneObjective(_pop);
00067         }
00068         else if (nObjectives == 2)
00069         {
00070             // two objectives (the two objectives function is still to implement)
00071             mObjectives(_pop);
00072         }
00073         else if (nObjectives > 2)
00074         {
00075             // more than two objectives
00076             mObjectives(_pop);
00077         }
00078         else
00079         {
00080             // problem with the number of objectives
00081             throw std::runtime_error("Problem with the number of objectives in moeoNonDominatedSortingFitnessAssignment");
00082         }
00083         // a higher fitness is better, so the values need to be inverted
00084         double max = _pop[0].fitness();
00085         for (unsigned int i=1 ; i<_pop.size() ; i++)
00086         {
00087             max = std::max(max, _pop[i].fitness());
00088         }
00089         for (unsigned int i=0 ; i<_pop.size() ; i++)
00090         {
00091             _pop[i].fitness(max - _pop[i].fitness());
00092         }
00093     }
00094 
00095 
00101     void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec)
00102     {
00103         for (unsigned int i=0; i<_pop.size(); i++)
00104         {
00105             // if _pop[i] is dominated by _objVec
00106             if ( comparator(_pop[i].objectiveVector(), _objVec) )
00107             {
00108                 _pop[i].fitness(_pop[i].fitness()+1);
00109             }
00110         }
00111     }
00112 
00113 
00114 private:
00115 
00117     moeoObjectiveVectorComparator < ObjectiveVector > & comparator;
00119     moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator;
00121     class ObjectiveComparator : public moeoComparator < MOEOT >
00122     {
00123     public:
00129          const bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
00130          {
00131                 return cmp(_moeo1.objectiveVector(), _moeo2.objectiveVector());
00132          }
00133     private:
00135         moeoObjectiveObjectiveVectorComparator < ObjectiveVector > cmp;
00136     } objComparator;
00137 
00138 
00143     void oneObjective (eoPop < MOEOT > & _pop)
00144     {
00145         // sorts the population in the ascending order
00146         std::sort(_pop.begin(), _pop.end(), objComparator);
00147         // assign fitness values
00148         unsigned int rank = 1;
00149         _pop[_pop.size()-1].fitness(rank);
00150         for (unsigned int i=_pop.size()-2; i>=0; i--)
00151         {
00152             if (_pop[i].objectiveVector() != _pop[i+1].objectiveVector())
00153             {
00154                 rank++;
00155             }
00156             _pop[i].fitness(rank);
00157         }
00158     }
00159 
00160 
00165     void twoObjectives (eoPop < MOEOT > & _pop)
00166     {
00167         //... TO DO !
00168     }
00169 
00170 
00175     void mObjectives (eoPop < MOEOT > & _pop)
00176     {
00177         // S[i] = indexes of the individuals dominated by _pop[i]
00178         std::vector < std::vector<unsigned int> > S(_pop.size());
00179         // n[i] = number of individuals that dominate the individual _pop[i]
00180         std::vector < unsigned int > n(_pop.size(), 0);
00181         // fronts: F[i] = indexes of the individuals contained in the ith front
00182         std::vector < std::vector<unsigned int> > F(_pop.size()+2);
00183         // used to store the number of the first front
00184         F[1].reserve(_pop.size());
00185         for (unsigned int p=0; p<_pop.size(); p++)
00186         {
00187             for (unsigned int q=0; q<_pop.size(); q++)
00188             {
00189                 // if q is dominated by p
00190                 if ( comparator(_pop[q].objectiveVector(), _pop[p].objectiveVector()) )
00191                 {
00192                     // add q to the set of solutions dominated by p
00193                     S[p].push_back(q);
00194                 }
00195                 // if p is dominated by q
00196                 else if  ( comparator(_pop[p].objectiveVector(), _pop[q].objectiveVector()) )
00197                 {
00198                     // increment the domination counter of p
00199                     n[p]++;
00200                 }
00201             }
00202             // if no individual dominates p
00203             if (n[p] == 0)
00204             {
00205                 // p belongs to the first front
00206                 _pop[p].fitness(1);
00207                 F[1].push_back(p);
00208             }
00209         }
00210         // front counter
00211         unsigned int counter=1;
00212         unsigned int p,q;
00213         while (! F[counter].empty())
00214         {
00215             // used to store the number of the next front
00216             F[counter+1].reserve(_pop.size());
00217             for (unsigned int i=0; i<F[counter].size(); i++)
00218             {
00219                 p = F[counter][i];
00220                 for (unsigned int j=0; j<S[p].size(); j++)
00221                 {
00222                     q = S[p][j];
00223                     n[q]--;
00224                     // if no individual dominates q anymore
00225                     if (n[q] == 0)
00226                     {
00227                         // q belongs to the next front
00228                         _pop[q].fitness(counter+1);
00229                         F[counter+1].push_back(q);
00230                     }
00231                 }
00232             }
00233             counter++;
00234         }
00235     }
00236 
00237 };
00238 
00239 #endif /*MOEOFASTNONDOMINATEDSORTINGFITNESSASSIGNMENT_H_*/

Generated on Mon Jul 2 16:05:01 2007 for ParadisEO-MOEO by  doxygen 1.4.7