EvolvingObjects
|
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