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
00027
00028 #ifndef eoBitOp_h
00029 #define eoBitOp_h
00030
00031
00032
00033 #include <algorithm>
00034 #include <utils/eoRNG.h>
00035 #include <eoInit.h>
00036 #include <ga/eoBit.h>
00037
00038
00044 template<class Chrom> class eoOneBitFlip: public eoMonOp<Chrom>
00045 {
00046 public:
00048 virtual std::string className() const { return "eoOneBitFlip"; }
00049
00054 bool operator()(Chrom& chrom)
00055 {
00056 unsigned i = eo::rng.random(chrom.size());
00057 chrom[i] = (chrom[i]) ? false : true;
00058 return true;
00059 }
00060 };
00061
00067 template<class Chrom> class eoDetBitFlip: public eoMonOp<Chrom>
00068 {
00069 public:
00075 eoDetBitFlip(const unsigned& _num_bit = 1): num_bit(_num_bit) {}
00076
00078 virtual std::string className() const { return "eoDetBitFlip"; }
00079
00084 bool operator()(Chrom& chrom)
00085 {
00086
00087 for (unsigned k=0; k<num_bit; k++)
00088 {
00089 unsigned i = eo::rng.random(chrom.size());
00090 chrom[i] = (chrom[i]) ? false : true;
00091 }
00092 return true;
00093 }
00094 private:
00095 unsigned num_bit;
00096 };
00097
00098
00104 template<class Chrom> class eoBitMutation: public eoMonOp<Chrom>
00105 {
00106 public:
00111 eoBitMutation(const double& _rate = 0.01, bool _normalize=false):
00112 rate(_rate), normalize(_normalize) {}
00113
00115 virtual std::string className() const { return "eoBitMutation"; }
00116
00121 bool operator()(Chrom& chrom)
00122 {
00123 double actualRate = (normalize ? rate/chrom.size() : rate);
00124 bool changed_something = false;
00125 for (unsigned i = 0; i < chrom.size(); i++)
00126 if (eo::rng.flip(actualRate))
00127 {
00128 chrom[i] = !chrom[i];
00129 changed_something = true;
00130 }
00131
00132 return changed_something;
00133 }
00134
00135 private:
00136 double rate;
00137 bool normalize;
00138 };
00139
00140
00146 template<class Chrom> class eoBitInversion: public eoMonOp<Chrom>
00147 {
00148 public:
00150 virtual std::string className() const { return "eoBitInversion"; }
00151
00156 bool operator()(Chrom& chrom)
00157 {
00158
00159 unsigned u1 = eo::rng.random(chrom.size() + 1) , u2;
00160 do u2 = eo::rng.random(chrom.size() + 1); while (u1 == u2);
00161 unsigned r1 = std::min(u1, u2), r2 = std::max(u1, u2);
00162
00163 std::reverse(chrom.begin() + r1, chrom.begin() + r2);
00164 return true;
00165 }
00166 };
00167
00168
00174 template<class Chrom> class eoBitNext: public eoMonOp<Chrom>
00175 {
00176 public:
00178 virtual std::string className() const { return "eoBitNext"; }
00179
00184 bool operator()(Chrom& chrom)
00185 {
00186 for (int i = chrom.size() - 1; i >= 0; i--)
00187 if (chrom[i])
00188 {
00189 chrom[i] = 0;
00190 continue;
00191 }
00192 else
00193 {
00194 chrom[i] = 1;
00195 break;
00196 }
00197
00198 return true;
00199 }
00200 };
00201
00202
00208 template<class Chrom> class eoBitPrev: public eoMonOp<Chrom>
00209 {
00210 public:
00212 virtual std::string className() const { return "eoBitPrev"; }
00213
00218 bool operator()(Chrom& chrom)
00219 {
00220 for (int i = chrom.size() - 1; i >= 0; i--)
00221 if (chrom[i])
00222 {
00223 chrom[i] = 0;
00224 break;
00225 }
00226 else
00227 {
00228 chrom[i] = 1;
00229 continue;
00230 }
00231
00232 return true;
00233 }
00234 };
00235
00236
00242 template<class Chrom> class eo1PtBitXover: public eoQuadOp<Chrom>
00243 {
00244 public:
00246 virtual std::string className() const { return "eo1PtBitXover"; }
00247
00253 bool operator()(Chrom& chrom1, Chrom& chrom2)
00254 {
00255 unsigned site = eo::rng.random(std::min(chrom1.size(), chrom2.size()));
00256
00257 if (!std::equal(chrom1.begin(), chrom1.begin()+site, chrom2.begin()))
00258 {
00259
00260 std::swap_ranges(chrom1.begin(), chrom1.begin() + site, chrom2.begin());
00261
00262 return true;
00263 }
00264 return false;
00265 }
00266 };
00267
00268
00274 template<class Chrom> class eoUBitXover: public eoQuadOp<Chrom>
00275 {
00276 public:
00278 eoUBitXover(const float& _preference = 0.5): preference(_preference)
00279 {
00280 if ( (_preference <= 0.0) || (_preference >= 1.0) )
00281 std::runtime_error("UxOver --> invalid preference");
00282 }
00284 virtual std::string className() const { return "eoUBitXover"; }
00285
00292 bool operator()(Chrom& chrom1, Chrom& chrom2)
00293 {
00294 if ( chrom1.size() != chrom2.size())
00295 std::runtime_error("UxOver --> chromosomes sizes don't match" );
00296 bool changed = false;
00297 for (unsigned int i=0; i<chrom1.size(); i++)
00298 {
00299 if (chrom1[i] != chrom2[i] && eo::rng.flip(preference))
00300 {
00301 bool tmp = chrom1[i];
00302 chrom1[i]=chrom2[i];
00303 chrom2[i] = tmp;
00304 changed = true;
00305 }
00306 }
00307 return changed;
00308 }
00309 private:
00310 float preference;
00311 };
00312
00313
00319 template<class Chrom> class eoNPtsBitXover: public eoQuadOp<Chrom>
00320 {
00321 public:
00323 eoNPtsBitXover(const unsigned& _num_points = 2): num_points(_num_points)
00324 {
00325 if (num_points < 1)
00326 std::runtime_error("NxOver --> invalid number of points");
00327 }
00328
00330 virtual std::string className() const { return "eoNPtsBitXover"; }
00331
00337 bool operator()(Chrom& chrom1, Chrom& chrom2)
00338 {
00339 unsigned max_size = std::min(chrom1.size(), chrom2.size());
00340 unsigned max_points = std::min(max_size - 1, num_points);
00341
00342 std::vector<bool> points(max_size, false);
00343
00344
00345 do {
00346 unsigned bit = eo::rng.random(max_size) + 1;
00347 if (points[bit])
00348 continue;
00349 else
00350 {
00351 points[bit] = true;
00352 max_points--;
00353 }
00354 } while (max_points);
00355
00356
00357
00358 bool change = false;
00359 for (unsigned bit = 1; bit < points.size(); bit++)
00360 {
00361 if (points[bit])
00362 change = !change;
00363
00364 if (change)
00365 {
00366 typename Chrom::AtomType tmp= chrom1[bit];
00367 chrom1[bit] = chrom2[bit];
00368 chrom2[bit] = tmp;
00369 }
00370 }
00371
00372 return true;
00373 }
00374
00375 private:
00376 unsigned num_points;
00377 };
00378
00379
00380
00388 template<class Chrom> class eoBitGxOver: public eoQuadOp<Chrom>
00389 {
00390 public:
00392 eoBitGxOver(const unsigned _gene_size, const unsigned _num_points = 2):
00393 gene_size(_gene_size), num_points(_num_points)
00394 {
00395 if (gene_size < 1)
00396 std::runtime_error("GxOver --> invalid gene size");
00397 if (num_points < 1)
00398 std::runtime_error("GxOver --> invalid number of points");
00399 }
00400
00402 virtual std::string className() const { return "eoBitGxOver"; }
00403
00409 bool operator()(Chrom& chrom1, Chrom& chrom2)
00410 {
00411 unsigned max_genes = std::min(chrom1.size(), chrom2.size()) / gene_size;
00412 unsigned cut_genes = std::min(max_genes, num_points);
00413
00414 std::vector<bool> points(max_genes, false);
00415
00416
00417 do {
00418 unsigned bit = eo::rng.random(max_genes);
00419 if (points[bit])
00420 continue;
00421 else
00422 {
00423 points[bit] = true;
00424 cut_genes--;
00425 }
00426 } while (cut_genes);
00427
00428
00429 for (unsigned i = 0; i < points.size(); i++)
00430 if (points[i])
00431 std::swap_ranges(chrom1.begin() + i * gene_size,
00432 chrom1.begin() + i * gene_size + gene_size,
00433 chrom2.begin() + i * gene_size);
00434
00435 return true;
00436 }
00437
00438 private:
00439 unsigned gene_size;
00440 unsigned num_points;
00441 };
00442
00443
00444
00445
00447 #endif
00448