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