eoFlOrBinOp.h

00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // eoFlOrBinOp.h
00005 // (c) Marc Schoenauer - Maarten Keijzer 2000-2003
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: Marc.Schoenauer@inria.fr
00022              mkeijzer@cs.vu.nl
00023  */
00024 //-----------------------------------------------------------------------------
00025 
00026 #ifndef _eoFlOrBinOp_h
00027 #define _eoFlOrBinOp_h
00028 
00029 #include <eoFunctor.h>
00030 #include <eoOp.h>
00031 
00042 
00043 //                eoFlOrAllAtomBinOp
00045 
00048 template <class EOT>
00049 class eoFlOrAllAtomBinOp : public eoBinOp<EOT>
00050 {
00051 public :
00052 
00053   typedef typename EOT::AtomType AtomType;
00054 
00056   eoFlOrAllAtomBinOp( eoBinOp<AtomType>& _op, float _rate = 1.0):
00057     op(_op), rate( _rate ) {}
00058 
00060   bool operator()(EOT & _eo1, const EOT & _eo2)
00061   {
00062     if (_eo1.size() != _eo2.size())
00063       {
00064         string s = "Operand size don't match in " + className();
00065         throw runtime_error(s);
00066       }
00067     bool changed = false;
00068     for ( unsigned i = 0; i < _eo1.size(); i++ ) {
00069       if ( rng.flip( rate ) ) {
00070         bool changedHere = op( _eo1[i], _eo2[i] );
00071         changed |= changedHere;
00072       }
00073     }
00074     return changed;
00075   }
00076 
00078   virtual string className() const { return "eoFlOrAllAtomBinOp"; }
00079 
00080 private:
00081   double rate;
00082   eoBinOp<AtomType> & op;
00083 };
00084 
00086 //                 eoFlOrKAtomBinOp
00088 
00091 template <class EOT>
00092 class eoFlOrKAtomBinOp : public eoBinOp<EOT>
00093 {
00094 public :
00095 
00096   typedef typename EOT::AtomType AtomType;
00097 
00099   eoFlOrAtomBinOp( eoBinOp<AtomType>& _op, unsigned _k = 1):
00100     op(_op), k( _k ) {}
00101 
00103   bool operator()(EOT & _eo1, const EOT & _eo2)
00104   {
00105     if (_eo1.size() != _eo2.size())
00106       {
00107         string s = "Operand size don't match in " + className();
00108         throw runtime_error(s);
00109       }
00110 
00111     bool changed = false;
00112     for ( unsigned i = 0; i < k; i++ ) // TODO: check that we don't do twice the same
00113       {
00114         unsigned where = eo::rng.random(_eo1.size());
00115         bool changedHere = op( _eo1[where], _eo2[where] );
00116         changed |= changedHere;
00117       }
00118     return changed;
00119   }
00120 
00122   virtual string className() const { return "eoFlOrKAtomBinOp"; }
00123 
00124 private:
00125   unsigned k;
00126   eoBinOp<AtomType> & op;
00127 };
00128 
00129 
00131 //                        eoFlOrUniformBinOp
00133 
00135 template <class EOT>
00136 class eoFlOrUniformBinOp : public eoBinOp<EOT>
00137 {
00138 public :
00139 
00140   typedef typename EOT::AtomType AtomType;
00141 
00143   eoFlOrUniformBinOp(double _rate=0.5) : eoBinOp<EOT>(_size),
00144     rate(_rate) {}
00145 
00147   bool operator()(EOT & _eo1, const EOT & _eo2)
00148   {
00149     unsigned i;
00150     Atom tmp;
00151     if (_eo1.size() != _eo2.size())
00152       {
00153         string s = "Operand size don't match in " + className();
00154         throw runtime_error(s);
00155   }
00156     bool hasChanged = false;
00157     for (unsigned i=0; i<_eo1.size(); i++)
00158       {
00159         if ( (_eo1[i]!=_eo2[i]) && (eo::rng.filp(rate)) )
00160         {
00161           _eo1[i] = _eo2[i];
00162           hasChanged = true;
00163         }
00164       }
00165     return hasChanged;
00166   }
00167 
00169   virtual string className() const { return "eoFlOrUniformBinOp"; }
00170 
00171 private:
00172   double rate;
00173 };
00174 
00176 //                        eoFlOr1ptBinOp
00178 
00180 template <class EOT>
00181 class eoFlOr1ptBinOp : public eoBinOp<EOT>
00182 {
00183 public :
00184 
00185   typedef typename EOT::AtomType AtomType;
00186 
00188   eoVlUniformBinOp() {}
00189 
00191   bool operator()(EOT & _eo1, EOT & _eo2)
00192   {
00193     unsigned i;
00194     Atom tmp;
00195     if (_eo1.size() != _eo2.size())
00196       {
00197         string s = "Operand size don't match in " + className();
00198         throw runtime_error(s);
00199   }
00200     bool hasChanged = false;
00201     unsigned where = eo::rng.random(_eo1.size()-1);
00202     for (unsigned i=where+1; i<_eo1.size(); i++)
00203       {
00204         if ( (_eo1[i]!=_eo2[i]) )
00205         {
00206           _eo1[i] = _eo2[i];
00207           hasChanged = true;
00208         }
00209       }
00210     return hasChanged;
00211   }
00212 
00214   virtual string className() const { return "eoFlOr1ptBinOp"; }
00215 
00216 };
00217 
00218 
00219 #endif

Generated on Thu Apr 19 11:02:27 2007 for EO by  doxygen 1.4.7