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