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
00318 template<class Chrom> class eoNPtsBitXover : public eoQuadOp<Chrom>
00319 {
00320 public:
00321
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 unsigned max_size(std::min(chrom1.size(), chrom2.size()));
00339 unsigned max_points(std::min(max_size - 1, num_points));
00340 std::vector<bool> points(max_size, false);
00341
00342
00343 do {
00344 unsigned bit(eo::rng.random(max_size));
00345 if(points[bit])
00346 continue;
00347 else {
00348 points[bit] = true;
00349 --max_points;
00350 }
00351 } while(max_points);
00352
00353
00354 bool change(false);
00355 for (unsigned bit = 1; bit < points.size(); bit++) {
00356 if (points[bit])
00357 change = !change;
00358 if (change) {
00359 typename Chrom::AtomType tmp = chrom1[bit];
00360 chrom1[bit] = chrom2[bit];
00361 chrom2[bit] = tmp;
00362 }
00363 }
00364 return true;
00365 }
00366
00367 private:
00368
00370 unsigned num_points;
00371 };
00372
00373
00374
00382 template<class Chrom> class eoBitGxOver: public eoQuadOp<Chrom>
00383 {
00384 public:
00386 eoBitGxOver(const unsigned _gene_size, const unsigned _num_points = 2):
00387 gene_size(_gene_size), num_points(_num_points)
00388 {
00389 if (gene_size < 1)
00390 std::runtime_error("GxOver --> invalid gene size");
00391 if (num_points < 1)
00392 std::runtime_error("GxOver --> invalid number of points");
00393 }
00394
00396 virtual std::string className() const { return "eoBitGxOver"; }
00397
00403 bool operator()(Chrom& chrom1, Chrom& chrom2)
00404 {
00405 unsigned max_genes = std::min(chrom1.size(), chrom2.size()) / gene_size;
00406 unsigned cut_genes = std::min(max_genes, num_points);
00407
00408 std::vector<bool> points(max_genes, false);
00409
00410
00411 do {
00412 unsigned bit = eo::rng.random(max_genes);
00413 if (points[bit])
00414 continue;
00415 else
00416 {
00417 points[bit] = true;
00418 cut_genes--;
00419 }
00420 } while (cut_genes);
00421
00422
00423 for (unsigned i = 0; i < points.size(); i++)
00424 if (points[i])
00425 std::swap_ranges(chrom1.begin() + i * gene_size,
00426 chrom1.begin() + i * gene_size + gene_size,
00427 chrom2.begin() + i * gene_size);
00428
00429 return true;
00430 }
00431
00432 private:
00433 unsigned gene_size;
00434 unsigned num_points;
00435 };
00436
00437
00438
00439
00441 #endif
00442