EvolvingObjects
|
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_ */