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

Generated on Thu Oct 19 05:06:35 2006 for EO by  doxygen 1.3.9.1