EvolvingObjects
eoLinearTopology.h
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // eoLinearTopology.h
00005 // (c) OPAC 2007
00006 /*
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     Contact: thomas.legrand@lifl.fr
00022              clive.canape@inria.fr
00023  */
00024 //-----------------------------------------------------------------------------
00025 
00026 #ifndef EOLINEARTOPOLOGY_H_
00027 #define EOLINEARTOPOLOGY_H_
00028 
00029 //-----------------------------------------------------------------------------
00030 #include <eoPop.h>
00031 #include <eoTopology.h>
00032 #include <eoSocialNeighborhood.h>
00033 //-----------------------------------------------------------------------------
00034 
00035 
00043 template < class POT > class eoLinearTopology:public eoTopology <
00044             POT >
00045 {
00046 
00047 public:
00048 
00053     eoLinearTopology (unsigned _neighborhoodSize):neighborhoodSize (_neighborhoodSize),isSetup(false){}
00054 
00055 
00062     void setup(const eoPop<POT> & _pop)
00063     {
00064         if (!isSetup)
00065         {
00066             // consitency check
00067             if (neighborhoodSize >= _pop.size()){
00068                 std::string s;
00069                 s.append (" Invalid neighborhood size in eoLinearTopology ");
00070                 throw std::runtime_error (s);
00071             }
00072 
00073             unsigned howManyNeighborhood=_pop.size()/ neighborhoodSize;
00074 
00075             // build all the neighborhoods
00076             for (unsigned i=0;i< howManyNeighborhood;i++)
00077             {
00078                 eoSocialNeighborhood<POT> currentNghd;
00079 
00080                 currentNghd.best(_pop[i*neighborhoodSize]);
00081                 for (unsigned k=i*neighborhoodSize;k < neighborhoodSize*(i+1);k++)
00082                 {
00083                     currentNghd.put(k);
00084                     if (_pop[k].fitness() > currentNghd.best().fitness())
00085                         currentNghd.best(_pop[k]);
00086                 }
00087                 neighborhoods.push_back(currentNghd);
00088             }
00089 
00090             // assign the last neighborhood to the remaining particles
00091             if (_pop.size()%neighborhoodSize !=0)
00092             {
00093                 for (unsigned z=_pop.size()-1;z >= (_pop.size()-_pop.size()%neighborhoodSize);z--){
00094                     neighborhoods.back().put(z);
00095 
00096                     if (_pop[z].fitness() > neighborhoods.back().best().fitness())
00097                         neighborhoods.back().best(_pop[z]);
00098                 }
00099             }
00100 
00101             isSetup=true;
00102         }
00103         else
00104         {
00105             // Should activate this part ?
00106             /*
00107                std::string s;
00108                s.append (" Linear topology already setup in eoLinearTopology");
00109                throw std::runtime_error (s);
00110                */
00111         }
00112 
00113     }
00114 
00115 
00120     unsigned retrieveNeighborhoodByIndice(unsigned _indice)
00121     {
00122         unsigned i=0;
00123         for (i=0;i< neighborhoods.size();i++)
00124         {
00125             if (neighborhoods[i].contains(_indice))
00126             {
00127                 return i;
00128             }
00129         }
00130         return i;
00131     }
00132 
00137     void updateNeighborhood(POT & _po,unsigned _indice)
00138   {
00139         // update the best fitness of the particle
00140         if (_po.fitness() > _po.best())
00141         {
00142           _po.best(_po.fitness());
00143           for(unsigned i=0;i<_po.size();i++)
00144             _po.bestPositions[i]=_po[i];
00145         }
00146 
00147         // update the best in its neighborhood
00148         unsigned theGoodNhbd= retrieveNeighborhoodByIndice(_indice);
00149         if (_po.fitness() > neighborhoods[theGoodNhbd].best().fitness())
00150         {
00151             neighborhoods[theGoodNhbd].best(_po);
00152         }
00153     }
00154 
00160     POT & best (unsigned  _indice)
00161     {
00162         unsigned theGoodNhbd= retrieveNeighborhoodByIndice(_indice);
00163 
00164         return (neighborhoods[theGoodNhbd].best());
00165     }
00166 
00167 
00168     /*
00169          * Return the global best of the topology
00170          */
00171         virtual POT & globalBest()
00172     {
00173         POT gBest,tmp;
00174         unsigned indGlobalBest=0;
00175         if(neighborhoods.size()==1)
00176                 return neighborhoods[0].best();
00177 
00178         gBest=neighborhoods[0].best();
00179         for(unsigned i=1;i<neighborhoods.size();i++)
00180         {
00181                 tmp=neighborhoods[i].best();
00182                 if(gBest.best() < tmp.best())
00183                 {
00184                         gBest=tmp;
00185                         indGlobalBest=i;
00186                 }
00187 
00188         }
00189         return neighborhoods[indGlobalBest].best();
00190     }
00191 
00195     void printOn()
00196     {
00197         for (unsigned i=0;i< neighborhoods.size();i++)
00198         {
00199             std::cout << "{ " ;
00200             for (unsigned j=0;j< neighborhoods[i].size();j++)
00201             {
00202                 std::cout << neighborhoods[i].get(j) << " ";
00203             }
00204             std::cout << "}" << std::endl;
00205         }
00206     }
00207 
00208 
00209 protected:
00210         std::vector<eoSocialNeighborhood<POT> >  neighborhoods;
00211     unsigned neighborhoodSize; // the size of each neighborhood
00212 
00213     bool isSetup;
00214 
00215 };
00216 
00217 #endif /*EOLINEARTOPOLOGY_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Friends