00001
00025 #include <magic/mmath.h>
00026 #include <magic/mstream.h>
00027 #include <magic/mclass.h>
00028 #include <magic/mtextstream.h>
00029
00030 #include "nhp/genes.h"
00031 #include "nhp/individual.h"
00032 #include "nhp/mutrecord.h"
00033 #include "nhp/mutator.h"
00034
00035 impl_dynamic (Gene, {Genstruct});
00036 impl_dynamic (BinaryGene, {Gene});
00037 impl_dynamic (AnyFloatGene, {Gene});
00038 impl_dynamic (FloatGene, {AnyFloatGene});
00039 impl_dynamic (BitFloatGene, {AnyFloatGene});
00040 impl_dynamic (AnyIntGene, {Gene});
00041 impl_dynamic (IntGene, {AnyIntGene});
00042 impl_dynamic (BitIntGene, {AnyIntGene});
00043 impl_dynamic (InterGene, {Gene});
00044
00045
00046
00047 double mutateFloat (double x, double rate, int bits)
00048 {
00049
00050 PackArray<int> binary (bits);
00051
00052
00053 return 0.0;
00054 }
00055
00057
00058
00059
00060
00061
00062
00063
00065
00066 Gene::Gene (const GeneticID& n, double mut) : Genstruct (n) {
00067 mutability = mut;
00068 }
00069
00070 void Gene::copy (const Genstruct& o) {
00071 copyGenstr (o);
00072 mutability = static_cast<const Gene&>(o).mutability;
00073 }
00074
00075
00077
00078
00079
00080
00081
00082
00083
00085
00086 BinaryGene::BinaryGene (const GeneticID& id, double mut, double initP) : Gene (id, mut) {
00087 ASSERT (initP>=0 && initP<=1);
00088
00089 mInitP = initP;
00090 init ();
00091 }
00092
00093 void BinaryGene::init () {
00094 mValue = (frnd()<mInitP)? 1:0;
00095 }
00096
00097 bool BinaryGene::pointMutate (const MutationRate& mut_rate) {
00098 const double phi = 0.22;
00099
00100
00101 if (false && mut_rate.autoAdaptation()) {
00102 double p=mutability*mut_rate.binaryRate();
00103 p = 1/(1+(1-p)/p*exp(-phi*gaussrnd(1)));
00104 if (p<0.01)
00105 p = 0.01;
00106 mutability = p/mut_rate.binaryRate();
00107 }
00108
00109
00110
00111
00112
00113 if (frnd()>mut_rate.binaryRate()*mutability)
00114 return false;
00115
00116 mValue = mValue? 0:1;
00117 return true;
00118 }
00119
00120 void BinaryGene::copy (const Genstruct& o) {
00121 Gene::copy (o);
00122 shallowCopy (static_cast<const BinaryGene&>(o));
00123 }
00124
00125 void BinaryGene::print (TextOStream& out) const {
00126 out.printf ("%c", mValue? '1':'0');
00127 }
00128
00129 DataOStream& BinaryGene::operator>> (DataOStream& out) const {
00130 out.name("id") << id;
00131 out.name("mutability") << mutability;
00132 out.name("value") << int(mValue);
00133 out.name("initP") << mInitP;
00134
00135 return out;
00136 }
00137
00138
00139
00141
00142
00143
00144
00145
00146
00147
00149
00150 AnyFloatGene::AnyFloatGene (const GeneticID& id, double mi, double ma, double mut) : Gene (id, mut) {
00151 ASSERTWITH (mi<=ma, format ("min (was %f) value must be <= than max value (was %f)"
00152 , mi, ma));
00153 mMin = mi;
00154 mMax = ma;
00155 }
00156
00157 void AnyFloatGene::copy (const Genstruct& o) {
00158 Gene::copy (o);
00159 shallowCopy (static_cast<const AnyFloatGene&>(o));
00160 }
00161
00162 void AnyFloatGene::shallowCopy (const AnyFloatGene& o) {
00163 mMin = o.mMin;
00164 mMax = o.mMax;
00165 }
00166
00167 void AnyFloatGene::check () const {
00168 ASSERT (mMin<mMax);
00169 Gene::check ();
00170 }
00171
00173
00174
00175
00176
00177
00178
00179
00181
00182 FloatGene::FloatGene (const GeneticID& id, double mi, double ma, double mut, double val) : AnyFloatGene (id, mi, ma, mut) {
00183 value = val;
00184 mVariance = 1;
00185 mMutator = NULL;
00186 mCircular = false;
00187
00188 if (val<mMin || val>mMax)
00189 init ();
00190 }
00191
00192 void FloatGene::init () {
00193 value = mMin + frnd ()*(mMax-mMin);
00194 }
00195
00196 void FloatGene::copy (const Genstruct& o) {
00197 AnyFloatGene::copy (o);
00198 shallowCopy (static_cast<const FloatGene&>(o));
00199 }
00200
00201 void FloatGene::shallowCopy (const FloatGene& o) {
00202 value = o.value;
00203 mVariance = o.mVariance;
00204 mMutator = o.mMutator;
00205 }
00206
00207 bool FloatGene::pointMutate (const MutationRate& mut_rate) {
00208
00209 if (false && mut_rate.autoAdaptation() && frnd()<mut_rate.doubleRate()) {
00210 mutability = fabs (mutability + gaussrnd (mutability*0.5));
00211 }
00212
00213 if (mMutator) {
00214 value = mMutator->mutate (value, mMin, mMax, mVariance*mut_rate.doubleVariance());
00215 } else
00216 if (mMax>mMin) {
00217
00218 if (frnd()<mut_rate.doubleRate()) {
00219 double delta = gaussrnd (mut_rate.doubleVariance());
00220 if (value+delta<mMin)
00221 delta = mMin;
00222 else if (value+delta>mMax)
00223 delta = mMax;
00224
00225 value += delta;
00226 }
00227 }
00228
00229
00230
00231
00232 return true;
00233 }
00234
00235 double FloatGene::equality (const Genstruct& o) const {
00236 const FloatGene& other = static_cast<const FloatGene&>(o);
00237 return fabs(value-((FloatGene&)other).value)/(mMax-mMin);
00238 }
00239
00240 void FloatGene::print (TextOStream& out) const {
00241 out.printf ("%s=%0.2f", (CONSTR) id, value);
00242 }
00243
00244 void FloatGene::check () const {
00245 AnyFloatGene::check ();
00246 ASSERT (value>=mMin);
00247 ASSERT (value<=mMax);
00248 }
00249
00250
00251
00253
00254
00255
00256
00257
00258
00259
00261
00262 BitFloatGene::BitFloatGene (const GeneticID& id, double mi, double ma, int bits, const StringMap& params, double mut) : AnyFloatGene (id, mi, ma, mut) {
00263 ASSERT (bits>=1 && bits<=32);
00264
00265 mBitCount = bits;
00266 for (int i=0; i<bits; i++)
00267 mBits.add (new BinaryGene (format("b%d", i)));
00268
00269 Gentainer* dummy = NULL;
00270 mBits.addPrivateGenes (*dummy, params);
00271 mBits.selfadjust (false);
00272
00273 trywith (mGrayCoded = getOrDefault (params, "BitFloatGene.graycoding", String(1)).toInt(),
00274 format ("Gene name='%s'", (CONSTR) id));
00275 }
00276
00277 void BitFloatGene::copy (const Genstruct& o) {
00278 AnyFloatGene::copy (o);
00279 shallowCopy (static_cast<const BitFloatGene&>(o));
00280 }
00281
00282 void BitFloatGene::shallowCopy (const BitFloatGene& o) {
00283 mBitCount = o.mBitCount;
00284 mBits.copy (o.mBits);
00285 mGrayCoded = o.mGrayCoded;
00286 }
00287
00288 double BitFloatGene::getvalue () const
00289 {
00290
00291 PackArray<int> bits (mBitCount);
00292 for (int i=0; i<mBitCount; i++)
00293 bits[i] = static_cast<const BinaryGene&> (*mBits.getGene(format("b%d",i))).getvalue();
00294
00295 if (mGrayCoded) {
00296
00297 for (int i=mBitCount-2; i>=0; i--)
00298 bits[i] = bits[i+1]^bits[i];
00299 }
00300
00301
00302 unsigned long int sum = 0;
00303 for (unsigned long int i=0, m=1; i < (uint) mBitCount; i++, m<<=1)
00304 sum |= m*bits[i];
00305
00306 return mMin+(mMax-mMin)*double(sum)/double((1<<mBitCount));
00307 }
00308
00309 void BitFloatGene::print (TextOStream& out) const {
00310 out.printf ("%s=", (CONSTR) id);
00311 mBits.print (out);
00312 }
00313
00314 void BitFloatGene::recombine (const Genstruct& ar, const Genstruct& br) {
00315 const BitFloatGene& a = static_cast<const BitFloatGene&> (ar);
00316 const BitFloatGene& b = static_cast<const BitFloatGene&> (br);
00317
00318 mBits.recombine (a.mBits, b.mBits);
00319 }
00320
00321 void BitFloatGene::check () const {
00322 AnyFloatGene::check ();
00323 ASSERT (getvalue()>=mMin);
00324 ASSERT (getvalue()<=mMax);
00325 mBits.check ();
00326 ASSERT (mBitCount>=1);
00327 ASSERT (mBitCount<1000);
00328 }
00329
00330
00331
00333
00334
00335
00336
00337
00338
00339
00341
00342 AnyIntGene::AnyIntGene (const GeneticID& id, int mi, int ma, double mut) : Gene (id, mut) {
00343 ASSERTWITH (mi<=ma, format ("min (was %f) value must be <= than max value (was %f)"
00344 , mi, ma));
00345 mMin = mi;
00346 mMax = ma;
00347 }
00348
00349 void AnyIntGene::copy (const Genstruct& o) {
00350 Gene::copy (o);
00351 shallowCopy (static_cast<const AnyIntGene&>(o));
00352 }
00353
00354 void AnyIntGene::shallowCopy (const AnyIntGene& o) {
00355 mMin = o.mMin;
00356 mMax = o.mMax;
00357 }
00358
00360
00361
00362
00363
00364
00365
00366
00368
00369 IntGene::IntGene (const GeneticID& nam, int mi, int ma, double mut, int val) : AnyIntGene (nam, mi, ma, mut) {
00370 ASSERTWITH (mi<ma, format ("min (was %f) value must be smaller than max value (was %f)"
00371 , mi, ma));
00372 mValue = val;
00373 if (val<mMin || val>mMax)
00374 init ();
00375 }
00376
00377 int IntGene::getvalue () const {
00378 return mValue;
00379 }
00380
00381 void IntGene::init () {
00382 mValue = mMin + rnd (mMax-mMin);
00383 }
00384
00385 void IntGene::copy (const Genstruct& o) {
00386 AnyIntGene::copy (o);
00387
00388 shallowCopy (static_cast<const IntGene&>(o));
00389 }
00390
00391 void IntGene::shallowCopy (const IntGene& o) {
00392 mValue = o.mValue;
00393 mMin = o.mMin;
00394 mMax = o.mMax;
00395 }
00396
00397 bool IntGene::pointMutate (const MutationRate& mut_rate) {
00398 switch (0) {
00399 case 0: {
00400 if (frnd()<=mut_rate.intRate()*mutability)
00401 init ();
00402 } break;
00403 case 1: {
00404 int delta;
00405 do {
00406 delta = int (gaussrnd (mut_rate.doubleVariance()*mutability));
00407 } while (mValue+delta<mMin || mValue+delta>mMax);
00408 mValue += delta;
00409 }
00410 };
00411 return true;
00412 }
00413
00414 double IntGene::equality (const Genstruct& o) const {
00415 const IntGene& other = static_cast<const IntGene&>(o);
00416 return double(abs(mValue-((IntGene&)other).mValue))/double(mMax-mMin);
00417 }
00418
00419 void IntGene::print (TextOStream& out) const {
00420 out.printf ("%s=%d", (CONSTR) id, mValue);
00421 }
00422
00423 void IntGene::check () const {
00424 AnyIntGene::check ();
00425 ASSERT (mValue>=mMin);
00426 ASSERT (mValue<=mMax);
00427 }
00428
00429
00430
00432
00433
00434
00435
00436
00437
00438
00440
00441 BitIntGene::BitIntGene (const GeneticID& id, int mi, int ma, int bits, const StringMap& params, double mut) : AnyIntGene (id, mi, ma, mut) {
00442 ASSERT (bits>=1 && bits<=32);
00443 ASSERTWITH (ma-mi+1==(1<<bits), format("Range (%d-%d) must match the number of bits (%d)",
00444 mi, ma, bits));
00445
00446 mBitCount = bits;
00447 for (int i=0; i<bits; i++)
00448 mBits.add (new BinaryGene (format("b%d", i)));
00449
00450 Gentainer* dummy = NULL;
00451 mBits.addPrivateGenes (*dummy, params);
00452 mBits.selfadjust (false);
00453
00454 trywith (mGrayCoded = getOrDefault (params, "BitIntGene.graycoding", String(1)).toInt (),
00455 (CONSTR) format ("Gene name='%s'", (CONSTR) id));
00456 }
00457
00458 void BitIntGene::copy (const Genstruct& o) {
00459 AnyIntGene::copy (o);
00460 shallowCopy (static_cast<const BitIntGene&>(o));
00461 }
00462
00463 void BitIntGene::shallowCopy (const BitIntGene& o) {
00464 mBitCount = o.mBitCount;
00465 mBits.copy (o.mBits);
00466 mGrayCoded = o.mGrayCoded;
00467 }
00468
00469 int BitIntGene::getvalue () const {
00470
00471 PackArray<int> bits (mBitCount);
00472 for (int i=0; i<mBitCount; i++)
00473 bits[i] = static_cast<const BinaryGene&> (*mBits.getGene(format("b%d",i))).getvalue();
00474
00475 if (mGrayCoded) {
00476
00477 for (int i=mBitCount-2; i>=0; i--)
00478 bits[i] = bits[i+1]^bits[i];
00479 }
00480
00481
00482 unsigned long int sum = 0;
00483 for (unsigned long int i=0, m=1; i < (uint) mBitCount; i++, m<<=1)
00484 sum |= m*bits[i];
00485
00486 return mMin + sum;
00487 }
00488
00489 void BitIntGene::print (TextOStream& out) const {
00490 out.printf ("%s=", (CONSTR) id);
00491 mBits.print (out);
00492 }
00493
00494 void BitIntGene::recombine (const Genstruct& ar, const Genstruct& br) {
00495 const BitIntGene& a = static_cast<const BitIntGene&> (ar);
00496 const BitIntGene& b = static_cast<const BitIntGene&> (br);
00497
00498 mBits.recombine (a.mBits, b.mBits);
00499 }
00500
00501 void BitIntGene::check () const {
00502 AnyIntGene::check ();
00503 ASSERT (getvalue()>=mMin);
00504 ASSERT (getvalue()<=mMax);
00505 mBits.check ();
00506 ASSERT (mBitCount>=1);
00507 ASSERT (mBitCount<1000);
00508 }
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00576
00577
00578
00579
00580
00581
00582
00584
00585 bool InterGene::execute (const GeneticMsg& msg) const {
00586 return msg.host.execute (GeneticMsg (targetGene, msg.host));
00587 }
00588
00589 void InterGene::copy (const Genstruct& o) {
00590 copyGenstr (o);
00591 shallowCopy (static_cast<const InterGene&>(o));
00592 }
00593
00594 void InterGene::print (TextOStream& out) const {
00595 out.printf ("%s->%s", (CONSTR) id, (CONSTR) targetGene);
00596 }
00597