EvolvingObjects
eoBitOp.h
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
 All Classes Namespaces Files Functions Variables Typedefs Friends