# eoFlOrQuadOp.h

    00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
    00002
    00003 //-----------------------------------------------------------------------------
    00004 // eoFlOrQuadOp.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@polytechnique.fr
    00022              mkeijzer@cs.vu.nl
    00023  */
    00024 //-----------------------------------------------------------------------------
    00025
    00026 #ifndef _eoFlOrQuadOp_h
    00027 #define _eoFlOrQuadOp_h
    00028
    00029 #include <eoFunctor.h>
    00030 #include <eoOp.h>
    00031
    00039
    00040 //                        eoFlOrAllAtomQuadOp
    00042
    00045 template <class EOT>
    00046 class eoFlOrAllAtomQuadOp : public eoQuadOp<EOT>
    00047 {
    00048 public :
    00049
    00050   typedef typename EOT::AtomType AtomType;
    00051
    00053   eoFlOrAllAtomQuadOp( eoQuadOp<AtomType>& _op, double _rate = 1):
    00054     op(_op), rate( _rate ) {}
    00055
    00057   bool operator()(EOT & _eo1, EOT & _eo2)
    00058   {
    00059     bool changed = false;
    00060     for ( unsigned i = 0; i < _eo1.size(); i++ ) {
    00061       if ( rng.flip( rate ) ) {
    00062         bool changedHere = op( _eo1[i], _eo2[i] );
    00063         changed |= changedHere;
    00064       }
    00065     }
    00066     return changed;
    00067   }
    00068
    00070   virtual string className() const { return "eoFlOrAllAtomQuadOp"; }
    00071
    00072 private:
    00073   double rate;
    00074   eoQuadOp<AtomType> & op;
    00075 };
    00076
    00078 //                        eoFlOrKAtomQuadOp
    00080
    00083 template <class EOT>
    00084 class eoFlOrKAtomQuadOp : public eoQuadOp<EOT>
    00085 {
    00086 public :
    00087
    00088   typedef typename EOT::AtomType AtomType;
    00089
    00091   eoFlOrAtomQuadOp( eoQuadOp<AtomType>& _op, unsigned _k = 1):
    00092     op(_op), k( _k ) {}
    00093
    00095   bool operator()(EOT & _eo1, const EOT & _eo2)
    00096   {
    00097     if (_eo1.size() != _eo2.size())
    00098       {
    00099         string s = "Operand size don't match in " + className();
    00100         throw runtime_error(s);
    00101       }
    00102
    00103     bool changed = false;
    00104     for ( unsigned i = 0; i < k; i++ ) // TODO: check that we don't do twice the same
    00105       {
    00106         unsigned where = eo::rng.random(_eo1.size());
    00107         bool changedHere = op( _eo1[where], _eo2[where] );
    00108         changed |= changedHere;
    00109       }
    00110     return changed;
    00111   }
    00112
    00114   virtual string className() const { return "eoFlOrKAtomQuadOp"; }
    00115
    00116 private:
    00117   unsigned k;
    00118   eoQuadOp<AtomType> & op;
    00119 };
    00120
    00121
    00123 //                        eoFlOrUniformQuadOp
    00125
    00126 template <class EOT>
    00127 class eoFlOrUniformQuadOp : public eoQuadOp<EOT>
    00128 {
    00129 public :
    00130
    00131   typedef typename EOT::AtomType AtomType;
    00132
    00134   eoVlUniformQuadOp(double _rate=0.5) : eoQuadOp<EOT>(_size),
    00135     rate(_rate) {}
    00136
    00138   bool operator()(EOT & _eo1, EOT & _eo2)
    00139   {
    00140     unsigned i;
    00141     Atom tmp;
    00142     if (_eo1.size() != _eo2.size())
    00143       {
    00144         string s = "Operand size don't match in " + className();
    00145         throw runtime_error(s);
    00146   }
    00147     bool hasChanged = false;
    00148     for (unsigned i=0; i<_eo1.size(); i++)
    00149       {
    00150         if ( (_eo1[i]!=_eo2[i]) && (eo::rng.filp(rate)) )
    00151         {
    00152           tmp = _eo1[i];
    00153           _eo1[i] = _eo2[i];
    00154           _eo2[i] = tmp;
    00155           hasChanged = true;
    00156         }
    00157       }
    00158     return hasChanged;
    00159   }
    00160
    00162   virtual string className() const { return "eoFlOrUniformQuadOp"; }
    00163
    00164 private:
    00165   double rate;
    00166 };
    00167
    00169 //                        eoFlOr1ptQuadOp
    00171
    00172 template <class EOT>
    00173 class eoFlOr1ptQuadOp : public eoQuadOp<EOT>
    00174 {
    00175 public :
    00176
    00177   typedef typename EOT::AtomType AtomType;
    00178
    00180   eoVlUniformQuadOp() {}
    00181
    00183   bool operator()(EOT & _eo1, EOT & _eo2)
    00184   {
    00185     unsigned i;
    00186     Atom tmp;
    00187     if (_eo1.size() != _eo2.size())
    00188       {
    00189         string s = "Operand size don't match in " + className();
    00190         throw runtime_error(s);
    00191   }
    00192     bool hasChanged = false;
    00193     unsigned where = eo::rng.random(_eo1.size()-1);
    00194     for (unsigned i=where+1; i<_eo1.size(); i++)
    00195       {
    00196         if ( (_eo1[i]!=_eo2[i]) )
    00197         {
    00198           tmp = _eo1[i];
    00199           _eo1[i] = _eo2[i];
    00200           _eo2[i] = tmp;
    00201           hasChanged = true;
    00202         }
    00203       }
    00204     return hasChanged;
    00205   }
    00206
    00208   virtual string className() const { return "eoFlOr1ptQuadOp"; }
    00209
    00210 };
    00211
    00212
    00213 #endif