00001 #include "../ECF_base.h"
00002 #include "Tree.h"
00003 #include "TreeCrxSimple.h"
00004
00005
00006 namespace Tree
00007 {
00008
00009 void TreeCrxSimple::registerParameters(StateP state)
00010 {
00011 myGenotype_->registerParameter(state, "crx.simple", (voidP) new double(0), ECF::DOUBLE);
00012 myGenotype_->registerParameter(state, "crx.simple.functionprob", (voidP) new double(0.9), ECF::DOUBLE);
00013 }
00014
00015
00016 bool TreeCrxSimple::initialize(StateP state)
00017 {
00018 voidP sptr = myGenotype_->getParameterValue(state, "crx.simple");
00019 probability_ = *((double*)sptr.get());
00020 sptr = myGenotype_->getParameterValue(state, "crx.simple.functionprob");
00021 funcChoiceProb_ = *((double*)sptr.get());
00022
00023 return true;
00024 }
00025
00026
00027 bool TreeCrxSimple::mate(GenotypeP gen1, GenotypeP gen2, GenotypeP ch)
00028 {
00029 Tree* male = (Tree*) (gen1.get());
00030 Tree* female = (Tree*) (gen2.get());
00031 Tree* child = (Tree*) (ch.get());
00032
00033 uint mIndex, fIndex;
00034 uint mRange, fRange;
00035 uint mNodeDepth, fNodeDepth, fNodeDepthSize;
00036
00037 mRange = (uint) male->size();
00038 fRange = (uint) female->size();
00039
00040
00041 std::vector <uint> maleLeafIndexes, maleNonLeafIndexes;
00042 for(uint i = 0; i < mRange; i++) {
00043 if( male->at( i )->size_ == 1 ) maleLeafIndexes.push_back( i );
00044 else maleNonLeafIndexes.push_back( i );
00045 }
00046
00047 std::vector <uint> femaleLeafIndexes, femaleNonLeafIndexes;
00048 for(uint i = 0; i < fRange; i++) {
00049 if( female->at( i )->size_ == 1 ) femaleLeafIndexes.push_back( i );
00050 else femaleNonLeafIndexes.push_back( i );
00051 }
00052
00053 uint nTries = 0;
00054 while(1) {
00055
00056 if(state_->getRandomizer()->getRandomDouble() > funcChoiceProb_ || maleNonLeafIndexes.empty()) {
00057 uint randomLeafIndex = state_->getRandomizer()->getRandomInteger(0 , (uint) maleLeafIndexes.size() - 1);
00058 mIndex = maleLeafIndexes [ randomLeafIndex ];
00059 }
00060 else {
00061 uint randomNonLeafIndex = state_->getRandomizer()->getRandomInteger(0 , (uint) maleNonLeafIndexes.size() - 1);
00062 mIndex = maleNonLeafIndexes [ randomNonLeafIndex ];
00063 }
00064
00065
00066 if(state_->getRandomizer()->getRandomDouble() > funcChoiceProb_ || femaleNonLeafIndexes.empty()) {
00067 uint randomLeafIndex = state_->getRandomizer()->getRandomInteger(0 , (uint) femaleLeafIndexes.size() - 1);
00068 fIndex = femaleLeafIndexes [ randomLeafIndex ];
00069 }
00070 else {
00071 uint randomNonLeafIndex = state_->getRandomizer()->getRandomInteger(0 , (uint) femaleNonLeafIndexes.size() - 1);
00072 fIndex = femaleNonLeafIndexes [ randomNonLeafIndex ];
00073 }
00074
00075 mNodeDepth = male->at( mIndex )->depth_;
00076 fNodeDepth = female->at( fIndex )->depth_;
00077
00078
00079 int maxDepth = fNodeDepth, depth;
00080 for(uint i = 0; i < female->at( fIndex )->size_; i++) {
00081 depth = female->at( fIndex + i )->depth_;
00082 maxDepth = depth > maxDepth ? depth : maxDepth;
00083 }
00084
00085 fNodeDepthSize = maxDepth - fNodeDepth;
00086 nTries++;
00087
00088 if(nTries > 4 || mNodeDepth + fNodeDepthSize <= male->maxDepth_ ) break;
00089 }
00090
00091 if(nTries > 4 && mNodeDepth + fNodeDepthSize > male->maxDepth_) {
00092 ECF_LOG(state_, 5, "TreeCrxSimple not successful.");
00093 return false;
00094 }
00095
00096 child->clear();
00097
00098
00099 child->maxDepth_ = male->maxDepth_;
00100 child->minDepth_ = male->minDepth_;
00101 child->startDepth_ = male->startDepth_;
00102
00103
00104 for(uint i = 0; i < mIndex; i++) {
00105 NodeP node = static_cast<NodeP> (new Node( male->at(i)->primitive_));
00106 child->push_back( node );
00107 child->at( i )->depth_ = male->at( i )->depth_;
00108 }
00109
00110 for(uint i = 0; i < female->at( fIndex )->size_; i++) {
00111 NodeP node = static_cast<NodeP> (new Node( female->at( fIndex + i)->primitive_));
00112 child->push_back( node );
00113 }
00114
00115 for(uint i = mIndex + male->at( mIndex )->size_; i < mRange; i++) {
00116 NodeP node = static_cast<NodeP> (new Node( male->at( i )->primitive_));
00117 child->push_back( node );
00118 }
00119
00120
00121 child->update();
00122
00123 return true;
00124 }
00125
00126 }