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: 2003/06/06 10:29:13 $ $Header: /cvsroot/eodev/eo/src/ga/eoBitOp.h,v 1.17 2003/06/06 10:29:13 maartenkeijzer Exp $ $Author: maartenkeijzer $
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 
00044 template<class Chrom> class eoOneBitFlip: public eoMonOp<Chrom>
00045 {
00046  public:
00048   virtual std::string className() const { return "eoOneBitFlip"; }
00049 
00054   bool operator()(Chrom& chrom)
00055     {
00056       unsigned i = eo::rng.random(chrom.size());
00057       chrom[i] = (chrom[i]) ? false : true;
00058       return true;
00059     }
00060 };
00061 
00067 template<class Chrom> class eoDetBitFlip: public eoMonOp<Chrom>
00068 {
00069  public:
00075   eoDetBitFlip(const unsigned& _num_bit = 1): num_bit(_num_bit) {}
00076 
00078   virtual std::string className() const { return "eoDetBitFlip"; }
00079 
00084   bool operator()(Chrom& chrom)
00085     {
00086       // does not check for duplicate: if someone volunteers ....
00087       for (unsigned k=0; k<num_bit; k++)
00088         {
00089           unsigned i = eo::rng.random(chrom.size());
00090           chrom[i] = (chrom[i]) ? false : true;
00091         }
00092       return true;
00093     }
00094  private:
00095   unsigned num_bit;
00096 };
00097 
00098 
00104 template<class Chrom> class eoBitMutation: public eoMonOp<Chrom>
00105 {
00106  public:
00111   eoBitMutation(const double& _rate = 0.01, bool _normalize=false): 
00112     rate(_rate), normalize(_normalize) {}
00113 
00115   virtual std::string className() const { return "eoBitMutation"; }
00116 
00121   bool operator()(Chrom& chrom)
00122     {
00123       double actualRate = (normalize ? rate/chrom.size() : rate);
00124       bool changed_something = false;
00125       for (unsigned i = 0; i < chrom.size(); i++)
00126             if (eo::rng.flip(actualRate))
00127         {
00128                 chrom[i] = !chrom[i];
00129             changed_something = true;
00130         }
00131 
00132         return changed_something;
00133     }
00134 
00135  private:
00136   double rate;
00137   bool normalize;                  // divide rate by chromSize
00138 };
00139 
00140 
00146 template<class Chrom> class eoBitInversion: public eoMonOp<Chrom>
00147 {
00148  public:
00150   virtual std::string className() const { return "eoBitInversion"; }
00151 
00156   bool operator()(Chrom& chrom)
00157     {
00158 
00159       unsigned u1 = eo::rng.random(chrom.size() + 1) , u2;
00160       do u2 = eo::rng.random(chrom.size() + 1); while (u1 == u2);
00161       unsigned r1 = std::min(u1, u2), r2 = std::max(u1, u2);
00162 
00163       std::reverse(chrom.begin() + r1, chrom.begin() + r2);
00164       return true;
00165     }
00166 };
00167 
00168 
00174 template<class Chrom> class eoBitNext: public eoMonOp<Chrom>
00175 {
00176  public:
00178   virtual std::string className() const { return "eoBitNext"; }
00179 
00184   bool operator()(Chrom& chrom)
00185     {
00186       for (int i = chrom.size() - 1; i >= 0; i--)
00187         if (chrom[i])
00188           {
00189             chrom[i] = 0;
00190             continue;
00191           }
00192         else
00193           {
00194             chrom[i] = 1;
00195             break;
00196           }
00197 
00198     return true;
00199     }
00200 };
00201 
00202 
00208 template<class Chrom> class eoBitPrev: public eoMonOp<Chrom>
00209 {
00210  public:
00212   virtual std::string className() const { return "eoBitPrev"; }
00213 
00218   bool operator()(Chrom& chrom)
00219     {
00220       for (int i = chrom.size() - 1; i >= 0; i--)
00221         if (chrom[i])
00222           {
00223             chrom[i] = 0;
00224             break;
00225           }
00226         else
00227           {
00228             chrom[i] = 1;
00229             continue;
00230           }
00231 
00232     return true;
00233     }
00234 };
00235 
00236 
00242 template<class Chrom> class eo1PtBitXover: public eoQuadOp<Chrom>
00243 {
00244  public:
00246   virtual std::string className() const { return "eo1PtBitXover"; }
00247 
00253   bool operator()(Chrom& chrom1, Chrom& chrom2)
00254     {
00255       unsigned site = eo::rng.random(std::min(chrom1.size(), chrom2.size()));
00256 
00257       if (!std::equal(chrom1.begin(), chrom1.begin()+site, chrom2.begin()))
00258       {
00259 
00260         std::swap_ranges(chrom1.begin(), chrom1.begin() + site, chrom2.begin());
00261 
00262         return true;
00263       }
00264       return false;
00265   }
00266 };
00267 
00268 
00274 template<class Chrom> class eoUBitXover: public eoQuadOp<Chrom>
00275 {
00276  public:
00278   eoUBitXover(const float& _preference = 0.5): preference(_preference)
00279     {
00280       if ( (_preference <= 0.0) || (_preference >= 1.0) )
00281         std::runtime_error("UxOver --> invalid preference");
00282     }
00284   virtual std::string className() const { return "eoUBitXover"; }
00285 
00292   bool operator()(Chrom& chrom1, Chrom& chrom2)
00293     {
00294       if ( chrom1.size() != chrom2.size())
00295             std::runtime_error("UxOver --> chromosomes sizes don't match" );
00296       bool changed = false;
00297       for (unsigned int i=0; i<chrom1.size(); i++)
00298         {
00299           if (chrom1[i] != chrom2[i] && eo::rng.flip(preference))
00300             {
00301               bool tmp = chrom1[i];
00302               chrom1[i]=chrom2[i];
00303               chrom2[i] = tmp;
00304               changed = true;
00305             }
00306         }
00307     return changed;
00308   }
00309     private:
00310       float preference;
00311 };
00312 
00313 
00319 template<class Chrom> class eoNPtsBitXover: public eoQuadOp<Chrom>
00320 {
00321  public:
00323   eoNPtsBitXover(const unsigned& _num_points = 2): num_points(_num_points)
00324     {
00325       if (num_points < 1)
00326         std::runtime_error("NxOver --> invalid number of points");
00327     }
00328 
00330   virtual std::string className() const { return "eoNPtsBitXover"; }
00331 
00337   bool operator()(Chrom& chrom1, Chrom& chrom2)
00338     {
00339       unsigned max_size = std::min(chrom1.size(), chrom2.size());
00340       unsigned max_points = std::min(max_size - 1, num_points);
00341 
00342       std::vector<bool> points(max_size, false);
00343 
00344       // select ranges of bits to swap
00345       do {
00346         unsigned bit = eo::rng.random(max_size) + 1;
00347         if (points[bit])
00348           continue;
00349         else
00350           {
00351             points[bit] = true;
00352             max_points--;
00353           }
00354       } while (max_points);
00355 
00356 
00357       // swap bits between chromosomes
00358       bool change = false;
00359       for (unsigned bit = 1; bit < points.size(); bit++)
00360         {
00361           if (points[bit])
00362             change = !change;
00363 
00364           if (change)
00365           {
00366                 typename Chrom::AtomType tmp= chrom1[bit];
00367                 chrom1[bit] = chrom2[bit];
00368                 chrom2[bit] = tmp;
00369           }
00370         }
00371 
00372     return true;
00373     }
00374 
00375  private:
00376   unsigned num_points;
00377 };
00378 
00379 
00380 
00388 template<class Chrom> class eoBitGxOver: public eoQuadOp<Chrom>
00389 {
00390  public:
00392   eoBitGxOver(const unsigned _gene_size, const unsigned _num_points = 2):
00393     gene_size(_gene_size), num_points(_num_points)
00394     {
00395       if (gene_size < 1)
00396         std::runtime_error("GxOver --> invalid gene size");
00397       if (num_points < 1)
00398         std::runtime_error("GxOver --> invalid number of points");
00399     }
00400 
00402   virtual std::string className() const { return "eoBitGxOver"; }
00403 
00409   bool operator()(Chrom& chrom1, Chrom& chrom2)
00410     {
00411       unsigned max_genes = std::min(chrom1.size(), chrom2.size()) / gene_size;
00412       unsigned cut_genes = std::min(max_genes, num_points);
00413 
00414       std::vector<bool> points(max_genes, false);
00415       
00416       // selects genes to swap
00417       do {
00418         unsigned bit = eo::rng.random(max_genes); 
00419         if (points[bit])
00420           continue;
00421         else
00422           {
00423             points[bit] = true;
00424             cut_genes--;
00425           }
00426       } while (cut_genes);
00427       
00428       // swaps genes
00429       for (unsigned i = 0; i < points.size(); i++)
00430         if (points[i])
00431           std::swap_ranges(chrom1.begin() + i * gene_size, 
00432                       chrom1.begin() + i * gene_size + gene_size, 
00433                       chrom2.begin() + i * gene_size);
00434 
00435     return true;
00436   }
00437 
00438  private:
00439   unsigned gene_size;
00440   unsigned num_points;
00441 };
00442 
00443 
00444 
00445 //-----------------------------------------------------------------------------
00447 #endif
00448 

Generated on Thu Oct 19 05:06:34 2006 for EO by  doxygen 1.3.9.1