EvolvingObjects
eoEsMutate.h
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; fill-column: 80; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // eoESMute.h : ES mutation
00005 // (c) Maarten Keijzer 2000 & GeNeura Team, 1998 for the EO part
00006 //     Th. Baeck 1994 and EEAAX 1999 for the ES part
00007 /*
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Lesser General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Lesser General Public License for more details.
00017 
00018     You should have received a copy of the GNU Lesser General Public
00019     License along with this library; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 
00022     Contact: todos@geneura.ugr.es, http://geneura.ugr.es
00023              marc.schoenauer@polytechnique.fr
00024                        http://eeaax.cmap.polytchnique.fr/
00025  */
00026 //-----------------------------------------------------------------------------
00027 
00028 
00029 #ifndef _EOESMUTATE_H
00030 #define _EOESMUTATE_H
00031 
00032 #include <cmath>
00033 #include <eoInit.h>
00034 #include <eoOp.h>
00035 #include <es/eoEsMutationInit.h>
00036 #include <es/eoEsSimple.h>
00037 #include <es/eoEsStdev.h>
00038 #include <es/eoEsFull.h>
00039 #include <utils/eoRealBounds.h>
00040 #include <utils/eoRNG.h>
00041 
00042 #ifndef M_PI
00043 #define M_PI 3.1415926535897932384626433832795
00044 #endif
00045 
00060 template <class EOT>
00061 class eoEsMutate : public eoMonOp< EOT >
00062 {
00063 public:
00064 
00066     typedef typename EOT::Fitness FitT;
00067 
00068 
00075     eoEsMutate(eoEsMutationInit& _init, eoRealVectorBounds& _bounds) : bounds(_bounds)
00076     {
00077         init(EOT(), _init); // initialize on actual type used
00078     }
00079 
00080 
00082     virtual ~eoEsMutate() {};
00083 
00084 
00091     virtual std::string className() const {return "eoESMutate";};
00092 
00093 
00098     virtual bool operator()( eoEsSimple<FitT>& _eo)
00099         {
00100             _eo.stdev *= exp(TauLcl * rng.normal());
00101             if (_eo.stdev < stdev_eps)
00102                 _eo.stdev = stdev_eps;
00103             // now apply to all
00104             for (unsigned i = 0; i < _eo.size(); ++i)
00105             {
00106                 _eo[i] += _eo.stdev * rng.normal();
00107             }
00108             bounds.foldsInBounds(_eo);
00109             return true;
00110         }
00111 
00112 
00129     virtual bool operator()( eoEsStdev<FitT>& _eo )
00130         {
00131             double global = TauGlb * rng.normal();
00132             for (unsigned i = 0; i < _eo.size(); i++)
00133             {
00134                 double stdev = _eo.stdevs[i];
00135                 stdev *= exp( global + TauLcl * rng.normal() );
00136                 if (stdev < stdev_eps)
00137                     stdev = stdev_eps;
00138                 _eo.stdevs[i] = stdev;
00139                 _eo[i] += stdev * rng.normal();
00140             }
00141             bounds.foldsInBounds(_eo);
00142             return true;
00143         }
00144 
00145 
00160     virtual bool operator()( eoEsFull<FitT> & _eo )
00161     // Code originally from Thomas Bäck
00162         {
00163             // First: mutate standard deviations (as for eoEsStdev<FitT>).
00164             double global = TauGlb * rng.normal();
00165             unsigned i;
00166             for (i = 0; i < _eo.size(); i++)
00167             {
00168                 double stdev = _eo.stdevs[i];
00169                 stdev *= exp( global + TauLcl*rng.normal() );
00170                 if (stdev < stdev_eps)
00171                     stdev = stdev_eps;
00172                 _eo.stdevs[i] = stdev;
00173             }
00174             // Mutate rotation angles.
00175             for (i = 0; i < _eo.correlations.size(); i++)
00176             {
00177                 _eo.correlations[i] += TauBeta * rng.normal();
00178                 if ( fabs(_eo.correlations[i]) > M_PI )
00179                 {
00180                     _eo.correlations[i] -= M_PI * (int) (_eo.correlations[i]/M_PI) ;
00181                 }
00182             }
00183             // Perform correlated mutations.
00184             unsigned k, n1, n2;
00185             double d1,d2, S, C;
00186             std::vector<double> VarStp(_eo.size());
00187             for (i = 0; i < _eo.size(); i++)
00188                 VarStp[i] = _eo.stdevs[i] * rng.normal();
00189             unsigned nq = _eo.correlations.size() - 1;
00190             for (k = 0; k < _eo.size()-1; k++)
00191             {
00192                 n1 = _eo.size() - k - 1;
00193                 n2 = _eo.size() - 1;
00194                 for (i = 0; i < k; i++)
00195                 {
00196                     d1 = VarStp[n1];
00197                     d2 = VarStp[n2];
00198                     S  = sin( _eo.correlations[nq] );
00199                     C  = cos( _eo.correlations[nq] );
00200                     VarStp[n2] = d1 * S + d2 * C;
00201                     VarStp[n1] = d1 * C - d2 * S;
00202                     n2--;
00203                     nq--;
00204                 }
00205             }
00206             for (i = 0; i < _eo.size(); i++)
00207                 _eo[i] += VarStp[i];
00208             bounds.foldsInBounds(_eo);
00209             return true;
00210         }
00211 
00212 
00213   private :
00214 
00216     void init(eoEsSimple<FitT>, eoEsMutationInit& _init)
00217     {
00218         unsigned size = bounds.size();
00219         TauLcl = _init.TauLcl();
00220         TauLcl /= sqrt(2*(double) size);
00221         std::cout << "Init<eoEsSimple>: tau local " << TauLcl << std::endl;
00222     }
00223 
00224 
00229     void init(eoEsStdev<FitT>, eoEsMutationInit& _init)
00230     {
00231         unsigned size = bounds.size();
00232         TauLcl = _init.TauLcl();
00233         TauGlb = _init.TauGlb();
00234         // renormalization
00235         TauLcl /= sqrt( 2.0 * sqrt(double(size)) );
00236         TauGlb /= sqrt( 2.0 * double(size) );
00237         std::cout << "Init<eoStDev>: tau local " << TauLcl << " et global " << TauGlb << std::endl;
00238     }
00239 
00240 
00245     void init(eoEsFull<FitT>, eoEsMutationInit& _init)
00246     {
00247         init(eoEsStdev<FitT>(), _init);
00248         TauBeta = _init.TauBeta();
00249         std::cout << "Init<eoEsFull>: tau local " << TauLcl << " et global " << TauGlb << std::endl;
00250     }
00251 
00252 
00254     double TauLcl;
00255 
00257     double TauGlb;
00258 
00260     double TauBeta;
00261 
00263     eoRealVectorBounds& bounds;
00264 
00279     static const double stdev_eps;
00280 };
00281 
00282 
00283 // Minimum value of stdevs, see declaration for details.
00284 template <class EOT>
00285 const double eoEsMutate<EOT>::stdev_eps = 1.0e-40;
00286 
00287 #endif
 All Classes Namespaces Files Functions Variables Typedefs Friends