# 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
    00059 template <class EOT>
    00060 class eoEsMutate : public eoMonOp< EOT >
    00061 {
    00062 public:
    00063
    00065     typedef typename EOT::Fitness FitT;
    00066
    00067
    00074     eoEsMutate(eoEsMutationInit& _init, eoRealVectorBounds& _bounds) : bounds(_bounds)
    00075     {
    00076         init(EOT(), _init); // initialize on actual type used
    00077     }
    00078
    00079
    00081     virtual ~eoEsMutate() {};
    00082
    00083
    00090     virtual std::string className() const {return "eoESMutate";};
    00091
    00092
    00097     virtual bool operator()( eoEsSimple<FitT>& _eo)
    00098         {
    00099             _eo.stdev *= exp(TauLcl * rng.normal());
    00100             if (_eo.stdev < stdev_eps)
    00101                 _eo.stdev = stdev_eps;
    00102             // now apply to all
    00103             for (unsigned i = 0; i < _eo.size(); ++i)
    00104             {
    00105                 _eo[i] += _eo.stdev * rng.normal();
    00106             }
    00107             bounds.foldsInBounds(_eo);
    00108             return true;
    00109         }
    00110
    00111
    00128     virtual bool operator()( eoEsStdev<FitT>& _eo )
    00129         {
    00130             double global = TauGlb * rng.normal();
    00131             for (unsigned i = 0; i < _eo.size(); i++)
    00132             {
    00133                 double stdev = _eo.stdevs[i];
    00134                 stdev *= exp( global + TauLcl * rng.normal() );
    00135                 if (stdev < stdev_eps)
    00136                     stdev = stdev_eps;
    00137                 _eo.stdevs[i] = stdev;
    00138                 _eo[i] += stdev * rng.normal();
    00139             }
    00140             bounds.foldsInBounds(_eo);
    00141             return true;
    00142         }
    00143
    00144
    00159     virtual bool operator()( eoEsFull<FitT> & _eo )
    00160     // Code originally from Thomas Bäck
    00161         {
    00162             // First: mutate standard deviations (as for eoEsStdev<FitT>).
    00163             double global = TauGlb * rng.normal();
    00164             unsigned i;
    00165             for (i = 0; i < _eo.size(); i++)
    00166             {
    00167                 double stdev = _eo.stdevs[i];
    00168                 stdev *= exp( global + TauLcl*rng.normal() );
    00169                 if (stdev < stdev_eps)
    00170                     stdev = stdev_eps;
    00171                 _eo.stdevs[i] = stdev;
    00172             }
    00173             // Mutate rotation angles.
    00174             for (i = 0; i < _eo.correlations.size(); i++)
    00175             {
    00176                 _eo.correlations[i] += TauBeta * rng.normal();
    00177                 if ( fabs(_eo.correlations[i]) > M_PI )
    00178                 {
    00179                     _eo.correlations[i] -= M_PI * (int) (_eo.correlations[i]/M_PI) ;
    00180                 }
    00181             }
    00182             // Perform correlated mutations.
    00183             unsigned k, n1, n2;
    00184             double d1,d2, S, C;
    00185             std::vector<double> VarStp(_eo.size());
    00186             for (i = 0; i < _eo.size(); i++)
    00187                 VarStp[i] = _eo.stdevs[i] * rng.normal();
    00188             unsigned nq = _eo.correlations.size() - 1;
    00189             for (k = 0; k < _eo.size()-1; k++)
    00190             {
    00191                 n1 = _eo.size() - k - 1;
    00192                 n2 = _eo.size() - 1;
    00193                 for (i = 0; i < k; i++)
    00194                 {
    00195                     d1 = VarStp[n1];
    00196                     d2 = VarStp[n2];
    00197                     S  = sin( _eo.correlations[nq] );
    00198                     C  = cos( _eo.correlations[nq] );
    00199                     VarStp[n2] = d1 * S + d2 * C;
    00200                     VarStp[n1] = d1 * C - d2 * S;
    00201                     n2--;
    00202                     nq--;
    00203                 }
    00204             }
    00205             for (i = 0; i < _eo.size(); i++)
    00206                 _eo[i] += VarStp[i];
    00207             bounds.foldsInBounds(_eo);
    00208             return true;
    00209         }
    00210
    00211
    00212   private :
    00213
    00215     void init(eoEsSimple<FitT>, eoEsMutationInit& _init)
    00216     {
    00217         unsigned size = bounds.size();
    00218         TauLcl = _init.TauLcl();
    00219         TauLcl /= sqrt(2*(double) size);
    00220         std::cout << "Init<eoEsSimple>: tau local " << TauLcl << std::endl;
    00221     }
    00222
    00223
    00228     void init(eoEsStdev<FitT>, eoEsMutationInit& _init)
    00229     {
    00230         unsigned size = bounds.size();
    00231         TauLcl = _init.TauLcl();
    00232         TauGlb = _init.TauGlb();
    00233         // renormalization
    00234         TauLcl /= sqrt( 2.0 * sqrt(double(size)) );
    00235         TauGlb /= sqrt( 2.0 * double(size) );
    00236         std::cout << "Init<eoStDev>: tau local " << TauLcl << " et global " << TauGlb << std::endl;
    00237     }
    00238
    00239
    00244     void init(eoEsFull<FitT>, eoEsMutationInit& _init)
    00245     {
    00246         init(eoEsStdev<FitT>(), _init);
    00247         TauBeta = _init.TauBeta();
    00248         std::cout << "Init<eoEsFull>: tau local " << TauLcl << " et global " << TauGlb << std::endl;
    00249     }
    00250
    00251
    00253     double TauLcl;
    00254
    00256     double TauGlb;
    00257
    00259     double TauBeta;
    00260
    00262     eoRealVectorBounds& bounds;
    00263
    00278     static const double stdev_eps;
    00279 };
    00280
    00281
    00282 // Minimum value of stdevs, see declaration for details.
    00283 template <class EOT>
    00284 const double eoEsMutate<EOT>::stdev_eps = 1.0e-40;
    00285
    00286 #endif