00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _eoVariableLengthCrossover_h
00027 #define _eoVariableLengthCrossover_h
00028
00029 #include <eoFunctor.h>
00030 #include <eoOp.h>
00031
00040 template <class Atom>
00041 class eoAtomExchange : public eoBF<unsigned, Atom &, bool>
00042 {
00043 public:
00045 virtual void randomize(unsigned int, unsigned int){}
00047 virtual std::string className() const=0;
00048 };
00049
00051 template <class Atom>
00052 class eoUniformAtomExchange: public eoAtomExchange<Atom>
00053 {
00054 public:
00055 eoUniformAtomExchange(double _rate=0.5):rate(_rate){}
00056
00061 void randomize(unsigned _size1, unsigned _size2)
00062 {
00063 mask.resize(_size1 + _size2);
00064 for (unsigned i=0; i<_size1+_size2; i++)
00065 mask[i]=eo::rng.flip(rate);
00066 }
00067
00069 bool operator()(unsigned _i, Atom & )
00070 {
00071 return mask[_i];
00072 }
00073
00075 virtual std::string className() const {return "eoUniformAtomExchange";}
00076
00077 private:
00078 double rate;
00079 std::vector<bool> mask;
00080 };
00081
00085
00088 template <class EOT>
00089 class eoVlAtomExchangeQuadOp : public eoQuadOp<EOT>
00090 {
00091 public :
00092
00093 typedef typename EOT::AtomType AtomType;
00094
00096 eoVlAtomExchangeQuadOp(unsigned _Min, unsigned _Max,
00097 eoAtomExchange<AtomType>& _atomExchange):
00098 Min(_Min), Max(_Max), atomExchange(_atomExchange) {}
00099
00100 bool operator()(EOT & _eo1, EOT & _eo2)
00101 {
00102 EOT tmp1, tmp2;
00103 unsigned index=0;
00104
00105 unsigned i, i1, i2;
00106 do {
00107
00108 atomExchange.randomize(_eo1.size(), _eo2.size());
00109
00110 i1=i2=0;
00111 for (i=0; i<_eo1.size(); i++)
00112 {
00113 if (atomExchange(i, _eo1[i]))
00114 i1++;
00115 else
00116 i2++;
00117 }
00118 for (i=0; i<_eo2.size(); i++)
00119 {
00120 if (atomExchange(i, _eo2[i]))
00121 i2++;
00122 else
00123 i1++;
00124 }
00125 index++;
00126 } while ( ( (i1<Min) || (i2<Min) ||
00127 (i1>Max) || (i2>Max) )
00128 && (index<10000) );
00129 if (index >= 10000)
00130 {
00131 std::cout << "Warning: impossible to generate individual of the right size in 10000 trials\n";
00132 return false;
00133 }
00134
00135 for (i=0; i<_eo1.size(); i++)
00136 {
00137 if (atomExchange(i, _eo1[i]))
00138 tmp1.push_back(_eo1[i]);
00139 else
00140 tmp2.push_back(_eo1[i]);
00141 }
00142 for (i=0; i<_eo2.size(); i++)
00143 {
00144 if (atomExchange(i, _eo2[i]))
00145 tmp2.push_back(_eo2[i]);
00146 else
00147 tmp1.push_back(_eo2[i]);
00148 }
00149
00150 _eo1.swap(tmp1);
00151 _eo2.swap(tmp2);
00152 return true;
00153 }
00154
00156 virtual std::string className() const
00157 {
00158 std::ostringstream os;
00159 os << "eoVlAtomExchangeQuadOp(" << atomExchange.className() << ")";
00160 return os.str();
00161 }
00162
00163 private:
00164 unsigned Min, Max;
00165 eoAtomExchange<AtomType> & atomExchange;
00166 };
00167
00171 template <class EOT>
00172 class eoInnerExchangeQuadOp : public eoQuadOp<EOT>
00173 {
00174 public :
00175
00176 typedef typename EOT::AtomType AtomType;
00177
00179 eoInnerExchangeQuadOp( eoQuadOp<AtomType>& _op, float _rate = 0.5):
00180 op(_op), rate( _rate ) {}
00181
00183 bool operator()(EOT & _eo1, EOT & _eo2)
00184 {
00185 unsigned size1 = _eo1.size(), size2 = _eo2.size(), minsize = ( size1 > size2)?size2:size1;
00186 bool changed = false;
00187 for ( unsigned i = 0; i < minsize; i ++ ) {
00188 if ( rng.flip( rate ) ) {
00189 bool changedHere = op( _eo1[i], _eo2[i] );
00190 changed |= changedHere;
00191 }
00192 }
00193 return changed;
00194 }
00195
00196 virtual std::string className() const
00197 {
00198 return "eoInnerExchangeQuadOp(" + op.className() + ")";
00199 }
00200
00201 private:
00202 float rate;
00203 eoQuadOp<AtomType> & op;
00204 };
00205
00206
00207
00208
00218 template <class EOT>
00219 class eoVlUniformQuadOp : public eoQuadOp<EOT>
00220 {
00221 public :
00222
00223 typedef typename EOT::AtomType AtomType;
00224
00225
00226 eoVlUniformQuadOp(unsigned _Min, unsigned _Max, double _rate=0.5) :
00227 Min(_Min), Max(_Max), rate(_rate) {}
00228
00229 bool operator()(EOT & _eo1, EOT & _eo2)
00230 {
00231 unsigned i;
00232 EOT tmp1, tmp2;
00233 unsigned index=0;
00234 do {
00235 for (i=0; i<_eo1.size(); i++)
00236 {
00237 if (eo::rng.flip(rate))
00238 tmp1.push_back(_eo1[i]);
00239 else
00240 tmp2.push_back(_eo1[i]);
00241
00242 }
00243 for (i=0; i<_eo2.size(); i++)
00244 {
00245 if (eo::rng.flip(rate))
00246 tmp1.push_back(_eo2[i]);
00247 else
00248 tmp2.push_back(_eo2[i]);
00249 }
00250 index++;
00251 } while ( ( (tmp1.size()<Min) || (tmp2.size()<Min) ||
00252 (tmp1.size()>Max) || (tmp2.size()>Max) )
00253 && (index<10000) );
00254 if (index >= 10000)
00255 {
00256 std::cout << "Warning: impossible to generate individual of the right size in 10000 trials\n";
00257 return false;
00258 }
00259
00260 _eo1.swap(tmp1);
00261 _eo2.swap(tmp2);
00262 return true;
00263 }
00264 private:
00265 unsigned Min, Max;
00266 double rate;
00267 };
00268
00269
00279 template <class EOT>
00280 class eoVlUniformBinOp : public eoBinOp<EOT>
00281 {
00282 public :
00283
00284 typedef typename EOT::AtomType AtomType;
00285
00286
00287 eoVlUniformBinOp(unsigned _Min, unsigned _Max, double _rate=0.5) :
00288 Min(_Min), Max(_Max), rate(_rate) {}
00289
00290 bool operator()(EOT & _eo1, const EOT & _eo2)
00291 {
00292 unsigned i;
00293 EOT tmp1;
00294 bool tmpIsOne=true, tmpIsTwo=true;
00295 unsigned index=0;
00296 do {
00297 for (i=0; i<_eo1.size(); i++)
00298 {
00299 if (eo::rng.flip(rate))
00300 {
00301 tmp1.push_back(_eo1[i]);
00302 tmpIsTwo = false;
00303 }
00304 else
00305 tmpIsOne=false;
00306
00307 }
00308 for (i=0; i<_eo2.size(); i++)
00309 {
00310 if (! eo::rng.flip(rate))
00311 {
00312 tmp1.push_back(_eo2[i]);
00313 tmpIsOne = false;
00314 }
00315 else
00316 tmpIsTwo = false;
00317 }
00318 index++;
00319 } while ( ( (tmp1.size()<Min) || (tmp1.size()>Max) )
00320 && (index<10000) );
00321
00322 if (index >= 10000)
00323 {
00324 std::cout << "Warning: impossible to generate individual of the right size in 10000 trials\n";
00325 return false;
00326 }
00327
00328 _eo1.swap(tmp1);
00329 if (tmpIsTwo)
00330 {
00331
00332 return false;
00333 }
00334 if (tmpIsOne)
00335 {
00336 return false;
00337 }
00338 return true;
00339 }
00340
00341 private:
00342 unsigned Min, Max;
00343 double rate;
00344 };
00345
00346
00347
00348 #endif