# 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