EvolvingObjects
|
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- 00002 00003 //----------------------------------------------------------------------------- 00004 // eoBitOp.h 00005 // (c) GeNeura Team, 2000 - EEAAX 2000 - Maarten Keijzer 2000 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: todos@geneura.ugr.es, http://geneura.ugr.es 00022 Marc.Schoenauer@polytechnique.fr 00023 mak@dhi.dk 00024 CVS Info: $Date: 2007-08-21 14:52:50 $ $Header: /home/nojhan/dev/eodev/eodev_cvs/eo/src/ga/eoBitOp.h,v 1.18 2007-08-21 14:52:50 kuepper Exp $ $Author: kuepper $ 00025 */ 00026 //----------------------------------------------------------------------------- 00027 00028 #ifndef eoBitOp_h 00029 #define eoBitOp_h 00030 00031 //----------------------------------------------------------------------------- 00032 00033 #include <algorithm> // swap_ranges 00034 #include <utils/eoRNG.h> 00035 #include <eoInit.h> // eoMonOp 00036 #include <ga/eoBit.h> 00037 00038 00046 template<class Chrom> class eoOneBitFlip: public eoMonOp<Chrom> 00047 { 00048 public: 00050 virtual std::string className() const { return "eoOneBitFlip"; } 00051 00056 bool operator()(Chrom& chrom) 00057 { 00058 unsigned i = eo::rng.random(chrom.size()); 00059 chrom[i] = !chrom[i]; 00060 return true; 00061 } 00062 }; 00063 00069 template<class Chrom> class eoDetBitFlip: public eoMonOp<Chrom> 00070 { 00071 public: 00077 eoDetBitFlip(const unsigned& _num_bit = 1): num_bit(_num_bit) {} 00078 00080 virtual std::string className() const { return "eoDetBitFlip"; } 00081 00086 bool operator()(Chrom& chrom) 00087 { 00088 // for duplicate checking see eoDetSingleBitFlip 00089 for (unsigned k=0; k<num_bit; k++) 00090 { 00091 unsigned i = eo::rng.random(chrom.size()); 00092 chrom[i] = !chrom[i]; 00093 } 00094 return true; 00095 } 00096 private: 00097 unsigned num_bit; 00098 }; 00099 00100 00106 template<class Chrom> class eoDetSingleBitFlip: public eoMonOp<Chrom> 00107 { 00108 public: 00114 eoDetSingleBitFlip(const unsigned& _num_bit = 1): num_bit(_num_bit) {} 00115 00117 virtual std::string className() const { return "eoDetSingleBitFlip"; } 00118 00123 bool operator()(Chrom& chrom) 00124 { 00125 std::vector< unsigned > selected; 00126 00127 // check for duplicate 00128 for (unsigned k=0; k<num_bit; k++) 00129 { 00130 unsigned temp; 00131 00132 do 00133 { 00134 temp = eo::rng.random( chrom.size() ); 00135 } 00136 while ( find( selected.begin(), selected.end(), temp ) != selected.end() ); 00137 00138 selected.push_back(temp); 00139 } 00140 00141 for ( size_t i = 0; i < selected.size(); ++i ) 00142 { 00143 chrom[i] = !chrom[i]; 00144 } 00145 00146 return true; 00147 } 00148 private: 00149 unsigned num_bit; 00150 }; 00151 00152 00158 template<class Chrom> class eoBitMutation: public eoMonOp<Chrom> 00159 { 00160 public: 00166 eoBitMutation(const double& _rate = 0.01, bool _normalize=false): 00167 rate(_rate), normalize(_normalize) {} 00168 00170 virtual std::string className() const { return "eoBitMutation"; } 00171 00176 bool operator()(Chrom& chrom) 00177 { 00178 double actualRate = (normalize ? rate/chrom.size() : rate); 00179 bool changed_something = false; 00180 for (unsigned i = 0; i < chrom.size(); i++) 00181 if (eo::rng.flip(actualRate)) 00182 { 00183 chrom[i] = !chrom[i]; 00184 changed_something = true; 00185 } 00186 00187 return changed_something; 00188 } 00189 00190 private: 00191 double rate; 00192 bool normalize; // divide rate by chromSize 00193 }; 00194 00195 00201 template<class Chrom> class eoBitInversion: public eoMonOp<Chrom> 00202 { 00203 public: 00205 virtual std::string className() const { return "eoBitInversion"; } 00206 00211 bool operator()(Chrom& chrom) 00212 { 00213 00214 unsigned u1 = eo::rng.random(chrom.size() + 1) , u2; 00215 do u2 = eo::rng.random(chrom.size() + 1); while (u1 == u2); 00216 unsigned r1 = std::min(u1, u2), r2 = std::max(u1, u2); 00217 00218 std::reverse(chrom.begin() + r1, chrom.begin() + r2); 00219 return true; 00220 } 00221 }; 00222 00223 00229 template<class Chrom> class eoBitNext: public eoMonOp<Chrom> 00230 { 00231 public: 00233 virtual std::string className() const { return "eoBitNext"; } 00234 00239 bool operator()(Chrom& chrom) 00240 { 00241 for (int i = chrom.size() - 1; i >= 0; i--) 00242 if (chrom[i]) 00243 { 00244 chrom[i] = 0; 00245 continue; 00246 } 00247 else 00248 { 00249 chrom[i] = 1; 00250 break; 00251 } 00252 00253 return true; 00254 } 00255 }; 00256 00257 00263 template<class Chrom> class eoBitPrev: public eoMonOp<Chrom> 00264 { 00265 public: 00267 virtual std::string className() const { return "eoBitPrev"; } 00268 00273 bool operator()(Chrom& chrom) 00274 { 00275 for (int i = chrom.size() - 1; i >= 0; i--) 00276 if (chrom[i]) 00277 { 00278 chrom[i] = 0; 00279 break; 00280 } 00281 else 00282 { 00283 chrom[i] = 1; 00284 continue; 00285 } 00286 00287 return true; 00288 } 00289 }; 00290 00291 00297 template<class Chrom> class eo1PtBitXover: public eoQuadOp<Chrom> 00298 { 00299 public: 00301 virtual std::string className() const { return "eo1PtBitXover"; } 00302 00308 bool operator()(Chrom& chrom1, Chrom& chrom2) 00309 { 00310 unsigned site = eo::rng.random(std::min(chrom1.size(), chrom2.size())); 00311 00312 if (!std::equal(chrom1.begin(), chrom1.begin()+site, chrom2.begin())) 00313 { 00314 00315 std::swap_ranges(chrom1.begin(), chrom1.begin() + site, chrom2.begin()); 00316 00317 return true; 00318 } 00319 return false; 00320 } 00321 }; 00322 00323 00329 template<class Chrom> class eoUBitXover: public eoQuadOp<Chrom> 00330 { 00331 public: 00333 eoUBitXover(const float& _preference = 0.5): preference(_preference) 00334 { 00335 if ( (_preference <= 0.0) || (_preference >= 1.0) ) 00336 std::runtime_error("UxOver --> invalid preference"); 00337 } 00339 virtual std::string className() const { return "eoUBitXover"; } 00340 00347 bool operator()(Chrom& chrom1, Chrom& chrom2) 00348 { 00349 if ( chrom1.size() != chrom2.size()) 00350 std::runtime_error("UxOver --> chromosomes sizes don't match" ); 00351 bool changed = false; 00352 for (unsigned int i=0; i<chrom1.size(); i++) 00353 { 00354 if (chrom1[i] != chrom2[i] && eo::rng.flip(preference)) 00355 { 00356 bool tmp = chrom1[i]; 00357 chrom1[i]=chrom2[i]; 00358 chrom2[i] = tmp; 00359 changed = true; 00360 } 00361 } 00362 return changed; 00363 } 00364 private: 00365 float preference; 00366 }; 00367 00368 00373 template<class Chrom> class eoNPtsBitXover : public eoQuadOp<Chrom> 00374 { 00375 public: 00376 00378 eoNPtsBitXover(const unsigned& _num_points = 2) : num_points(_num_points) 00379 { 00380 if (num_points < 1) 00381 std::runtime_error("NxOver --> invalid number of points"); 00382 } 00383 00385 virtual std::string className() const { return "eoNPtsBitXover"; } 00386 00392 bool operator()(Chrom& chrom1, Chrom& chrom2) { 00393 unsigned max_size(std::min(chrom1.size(), chrom2.size())); 00394 unsigned max_points(std::min(max_size - 1, num_points)); 00395 std::vector<bool> points(max_size, false); 00396 00397 // select ranges of bits to swap 00398 do { 00399 unsigned bit(eo::rng.random(max_size)); 00400 if(points[bit]) 00401 continue; 00402 else { 00403 points[bit] = true; 00404 --max_points; 00405 } 00406 } while(max_points); 00407 00408 // swap bits between chromosomes 00409 bool change(false); 00410 for (unsigned bit = 1; bit < points.size(); bit++) { 00411 if (points[bit]) 00412 change = !change; 00413 if (change) { 00414 typename Chrom::AtomType tmp = chrom1[bit]; 00415 chrom1[bit] = chrom2[bit]; 00416 chrom2[bit] = tmp; 00417 } 00418 } 00419 return true; 00420 } 00421 00422 private: 00423 00425 unsigned num_points; 00426 }; 00427 00428 00429 00437 template<class Chrom> class eoBitGxOver: public eoQuadOp<Chrom> 00438 { 00439 public: 00441 eoBitGxOver(const unsigned _gene_size, const unsigned _num_points = 2): 00442 gene_size(_gene_size), num_points(_num_points) 00443 { 00444 if (gene_size < 1) 00445 std::runtime_error("GxOver --> invalid gene size"); 00446 if (num_points < 1) 00447 std::runtime_error("GxOver --> invalid number of points"); 00448 } 00449 00451 virtual std::string className() const { return "eoBitGxOver"; } 00452 00458 bool operator()(Chrom& chrom1, Chrom& chrom2) 00459 { 00460 unsigned max_genes = std::min(chrom1.size(), chrom2.size()) / gene_size; 00461 unsigned cut_genes = std::min(max_genes, num_points); 00462 00463 std::vector<bool> points(max_genes, false); 00464 00465 // selects genes to swap 00466 do { 00467 unsigned bit = eo::rng.random(max_genes); 00468 if (points[bit]) 00469 continue; 00470 else 00471 { 00472 points[bit] = true; 00473 cut_genes--; 00474 } 00475 } while (cut_genes); 00476 00477 // swaps genes 00478 for (unsigned i = 0; i < points.size(); i++) 00479 if (points[i]) 00480 std::swap_ranges(chrom1.begin() + i * gene_size, 00481 chrom1.begin() + i * gene_size + gene_size, 00482 chrom2.begin() + i * gene_size); 00483 00484 return true; 00485 } 00486 00487 private: 00488 unsigned gene_size; 00489 unsigned num_points; 00490 }; 00491 00492 00493 00494 //----------------------------------------------------------------------------- 00496 #endif