moeoFastNonDominatedSortingFitnessAssignment.h

00001 /* 
00002 * <moeoFastNonDominatedSortingFitnessAssignment.h>
00003 * Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2007
00004 * (C) OPAC Team, LIFL, 2002-2007
00005 *
00006 * Arnaud Liefooghe
00007 *
00008 * This software is governed by the CeCILL license under French law and
00009 * abiding by the rules of distribution of free software.  You can  use,
00010 * modify and/ or redistribute the software under the terms of the CeCILL
00011 * license as circulated by CEA, CNRS and INRIA at the following URL
00012 * "http://www.cecill.info".
00013 *
00014 * As a counterpart to the access to the source code and  rights to copy,
00015 * modify and redistribute granted by the license, users are provided only
00016 * with a limited warranty  and the software's author,  the holder of the
00017 * economic rights,  and the successive licensors  have only  limited liability.
00018 *
00019 * In this respect, the user's attention is drawn to the risks associated
00020 * with loading,  using,  modifying and/or developing or reproducing the
00021 * software by the user in light of its specific status of free software,
00022 * that may mean  that it is complicated to manipulate,  and  that  also
00023 * therefore means  that it is reserved for developers  and  experienced
00024 * professionals having in-depth computer knowledge. Users are therefore
00025 * encouraged to load and test the software's suitability as regards their
00026 * requirements in conditions enabling the security of their systems and/or
00027 * data to be ensured and,  more generally, to use and operate it in the
00028 * same conditions as regards security.
00029 * The fact that you are presently reading this means that you have had
00030 * knowledge of the CeCILL license and that you accept its terms.
00031 *
00032 * ParadisEO WebSite : http://paradiseo.gforge.inria.fr
00033 * Contact: paradiseo-help@lists.gforge.inria.fr
00034 *
00035 */
00036 //-----------------------------------------------------------------------------
00037 
00038 #ifndef MOEOFASTNONDOMINATEDSORTINGFITNESSASSIGNMENT_H_
00039 #define MOEOFASTNONDOMINATEDSORTINGFITNESSASSIGNMENT_H_
00040 
00041 #include <vector>
00042 #include <eoPop.h>
00043 #include <comparator/moeoObjectiveObjectiveVectorComparator.h>
00044 #include <comparator/moeoObjectiveVectorComparator.h>
00045 #include <comparator/moeoParetoObjectiveVectorComparator.h>
00046 #include <fitness/moeoParetoBasedFitnessAssignment.h>
00047 
00048 
00056 template < class MOEOT >
00057 class moeoFastNonDominatedSortingFitnessAssignment : public moeoParetoBasedFitnessAssignment < MOEOT >
00058 {
00059 public:
00060 
00062     typedef typename MOEOT::ObjectiveVector ObjectiveVector;
00063 
00064 
00068     moeoFastNonDominatedSortingFitnessAssignment() : comparator(paretoComparator)
00069     {}
00070 
00071 
00076     moeoFastNonDominatedSortingFitnessAssignment(moeoObjectiveVectorComparator < ObjectiveVector > & _comparator) : comparator(_comparator)
00077     {}
00078 
00079 
00084     void operator()(eoPop < MOEOT > & _pop)
00085     {
00086         // number of objectives for the problem under consideration
00087         unsigned int nObjectives = MOEOT::ObjectiveVector::nObjectives();
00088         if (nObjectives == 1)
00089         {
00090             // one objective
00091             oneObjective(_pop);
00092         }
00093         else if (nObjectives == 2)
00094         {
00095             // two objectives (the two objectives function is still to implement)
00096             mObjectives(_pop);
00097         }
00098         else if (nObjectives > 2)
00099         {
00100             // more than two objectives
00101             mObjectives(_pop);
00102         }
00103         else
00104         {
00105             // problem with the number of objectives
00106             throw std::runtime_error("Problem with the number of objectives in moeoNonDominatedSortingFitnessAssignment");
00107         }
00108         // a higher fitness is better, so the values need to be inverted
00109         double max = _pop[0].fitness();
00110         for (unsigned int i=1 ; i<_pop.size() ; i++)
00111         {
00112             max = std::max(max, _pop[i].fitness());
00113         }
00114         for (unsigned int i=0 ; i<_pop.size() ; i++)
00115         {
00116             _pop[i].fitness(max - _pop[i].fitness());
00117         }
00118     }
00119 
00120 
00126     void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec)
00127     {
00128         for (unsigned int i=0; i<_pop.size(); i++)
00129         {
00130             // if _pop[i] is dominated by _objVec
00131             if ( comparator(_pop[i].objectiveVector(), _objVec) )
00132             {
00133                 _pop[i].fitness(_pop[i].fitness()+1);
00134             }
00135         }
00136     }
00137 
00138 
00139 private:
00140 
00142     moeoObjectiveVectorComparator < ObjectiveVector > & comparator;
00144     moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator;
00146     class ObjectiveComparator : public moeoComparator < MOEOT >
00147     {
00148     public:
00154          const bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
00155          {
00156                 return cmp(_moeo1.objectiveVector(), _moeo2.objectiveVector());
00157          }
00158     private:
00160         moeoObjectiveObjectiveVectorComparator < ObjectiveVector > cmp;
00161     } objComparator;
00162 
00163 
00168     void oneObjective (eoPop < MOEOT > & _pop)
00169     {
00170         // sorts the population in the ascending order
00171         std::sort(_pop.begin(), _pop.end(), objComparator);
00172         // assign fitness values
00173         unsigned int rank = 1;
00174         _pop[_pop.size()-1].fitness(rank);
00175         for (unsigned int i=_pop.size()-2; i>=0; i--)
00176         {
00177             if (_pop[i].objectiveVector() != _pop[i+1].objectiveVector())
00178             {
00179                 rank++;
00180             }
00181             _pop[i].fitness(rank);
00182         }
00183     }
00184 
00185 
00190     void twoObjectives (eoPop < MOEOT > & _pop)
00191     {
00192         //... TO DO !
00193     }
00194 
00195 
00200     void mObjectives (eoPop < MOEOT > & _pop)
00201     {
00202         // S[i] = indexes of the individuals dominated by _pop[i]
00203         std::vector < std::vector<unsigned int> > S(_pop.size());
00204         // n[i] = number of individuals that dominate the individual _pop[i]
00205         std::vector < unsigned int > n(_pop.size(), 0);
00206         // fronts: F[i] = indexes of the individuals contained in the ith front
00207         std::vector < std::vector<unsigned int> > F(_pop.size()+2);
00208         // used to store the number of the first front
00209         F[1].reserve(_pop.size());
00210         for (unsigned int p=0; p<_pop.size(); p++)
00211         {
00212             for (unsigned int q=0; q<_pop.size(); q++)
00213             {
00214                 // if q is dominated by p
00215                 if ( comparator(_pop[q].objectiveVector(), _pop[p].objectiveVector()) )
00216                 {
00217                     // add q to the set of solutions dominated by p
00218                     S[p].push_back(q);
00219                 }
00220                 // if p is dominated by q
00221                 else if  ( comparator(_pop[p].objectiveVector(), _pop[q].objectiveVector()) )
00222                 {
00223                     // increment the domination counter of p
00224                     n[p]++;
00225                 }
00226             }
00227             // if no individual dominates p
00228             if (n[p] == 0)
00229             {
00230                 // p belongs to the first front
00231                 _pop[p].fitness(1);
00232                 F[1].push_back(p);
00233             }
00234         }
00235         // front counter
00236         unsigned int counter=1;
00237         unsigned int p,q;
00238         while (! F[counter].empty())
00239         {
00240             // used to store the number of the next front
00241             F[counter+1].reserve(_pop.size());
00242             for (unsigned int i=0; i<F[counter].size(); i++)
00243             {
00244                 p = F[counter][i];
00245                 for (unsigned int j=0; j<S[p].size(); j++)
00246                 {
00247                     q = S[p][j];
00248                     n[q]--;
00249                     // if no individual dominates q anymore
00250                     if (n[q] == 0)
00251                     {
00252                         // q belongs to the next front
00253                         _pop[q].fitness(counter+1);
00254                         F[counter+1].push_back(q);
00255                     }
00256                 }
00257             }
00258             counter++;
00259         }
00260     }
00261 
00262 };
00263 
00264 #endif /*MOEOFASTNONDOMINATEDSORTINGFITNESSASSIGNMENT_H_*/

Generated on Fri Oct 12 15:16:04 2007 for ParadisEO-MOEO:MultiObjectiveEvolvingObjects by  doxygen 1.4.7