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 <eoPop.h>
00017 #include <moeoComparator.h>
00018 #include <moeoFitnessAssignment.h>
00019 #include <moeoObjectiveVectorComparator.h>
00020 
00028 template < class MOEOT >
00029 class moeoFastNonDominatedSortingFitnessAssignment : public moeoParetoBasedFitnessAssignment < MOEOT >
00030 {
00031 public:
00032 
00034     typedef typename MOEOT::ObjectiveVector ObjectiveVector;
00035 
00036 
00040     moeoFastNonDominatedSortingFitnessAssignment() : comparator(paretoComparator)
00041     {}
00042 
00043 
00048     moeoFastNonDominatedSortingFitnessAssignment(moeoObjectiveVectorComparator < ObjectiveVector > & _comparator) : comparator(_comparator)
00049     {}
00050 
00051 
00056     void operator()(eoPop < MOEOT > & _pop)
00057     {
00058         // number of objectives for the problem under consideration
00059         unsigned nObjectives = MOEOT::ObjectiveVector::nObjectives();
00060         if (nObjectives == 1)
00061         {
00062             // one objective
00063             oneObjective(_pop);
00064         }
00065         else if (nObjectives == 2)
00066         {
00067             // two objectives (the two objectives function is still to implement)
00068             mObjectives(_pop);
00069         }
00070         else if (nObjectives > 2)
00071         {
00072             // more than two objectives
00073             mObjectives(_pop);
00074         }
00075         else
00076         {
00077             // problem with the number of objectives
00078             throw std::runtime_error("Problem with the number of objectives in moeoNonDominatedSortingFitnessAssignment");
00079         }
00080         // a higher fitness is better, so the values need to be inverted
00081         double max = _pop[0].fitness();
00082         for (unsigned i=1 ; i<_pop.size() ; i++)
00083         {
00084             max = std::max(max, _pop[i].fitness());
00085         }
00086         for (unsigned i=0 ; i<_pop.size() ; i++)
00087         {
00088             _pop[i].fitness(max - _pop[i].fitness());
00089         }
00090     }
00091 
00092 
00100     void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec)
00101     {
00102         cout << "WARNING : updateByDeleting not implemented in moeoNonDominatedSortingFitnessAssignment" << endl;
00103     }
00104 
00105 
00106 private:
00107 
00109     moeoObjectiveVectorComparator < ObjectiveVector > & comparator;
00111     moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator;
00112 
00113 
00114 
00115 
00120     void oneObjective (eoPop < MOEOT > & _pop)
00121     {
00122         // Functor to compare two solutions on the first objective, then on the second, and so on
00123         moeoObjectiveComparator < MOEOT > objComparator;
00124         std::sort(_pop.begin(), _pop.end(), objComparator);
00125         for (unsigned i=0; i<_pop.size(); i++)
00126         {
00127             _pop[i].fitness(i+1);
00128         }
00129     }
00130 
00131 
00136     void twoObjectives (eoPop < MOEOT > & _pop)
00137     {
00138         //... TO DO !
00139     }
00140 
00141 
00146     void mObjectives (eoPop < MOEOT > & _pop)
00147     {
00148         // S[i] = indexes of the individuals dominated by _pop[i]
00149         std::vector < std::vector<unsigned> > S(_pop.size());
00150         // n[i] = number of individuals that dominate the individual _pop[i]
00151         std::vector < unsigned > n(_pop.size(), 0);
00152         // fronts: F[i] = indexes of the individuals contained in the ith front
00153         std::vector < std::vector<unsigned> > F(_pop.size()+1);
00154         // used to store the number of the first front
00155         F[1].reserve(_pop.size());
00156         for (unsigned p=0; p<_pop.size(); p++)
00157         {
00158             for (unsigned q=0; q<_pop.size(); q++)
00159             {
00160                 // if p dominates q
00161                 if ( comparator(_pop[p].objectiveVector(), _pop[q].objectiveVector()) )
00162                 {
00163                     // add q to the set of solutions dominated by p
00164                     S[p].push_back(q);
00165                 }
00166                 // if q dominates p
00167                 else if  ( comparator(_pop[q].objectiveVector(), _pop[p].objectiveVector()) )
00168                 {
00169                     // increment the domination counter of p
00170                     n[p]++;
00171                 }
00172             }
00173             // if no individual dominates p
00174             if (n[p] == 0)
00175             {
00176                 // p belongs to the first front
00177                 _pop[p].fitness(1);
00178                 F[1].push_back(p);
00179             }
00180         }
00181         // front counter
00182         unsigned counter=1;
00183         unsigned p,q;
00184         while (! F[counter].empty())
00185         {
00186             // used to store the number of the next front
00187             F[counter+1].reserve(_pop.size());
00188             for (unsigned i=0; i<F[counter].size(); i++)
00189             {
00190                 p = F[counter][i];
00191                 for (unsigned j=0; j<S[p].size(); j++)
00192                 {
00193                     q = S[p][j];
00194                     n[q]--;
00195                     // if no individual dominates q anymore
00196                     if (n[q] == 0)
00197                     {
00198                         // q belongs to the next front
00199                         _pop[q].fitness(counter+1);
00200                         F[counter+1].push_back(q);
00201                     }
00202                 }
00203             }
00204             counter++;
00205         }
00206     }
00207 
00208 };
00209 
00210 #endif /*MOEOFASTNONDOMINATEDSORTINGFITNESSASSIGNMENT_H_*/

Generated on Tue Apr 17 16:53:21 2007 for ParadisEO-MOEO by  doxygen 1.5.1