ECF 1.5
TreeCrxContextPreserved.cpp
1#include "../ECF_base.h"
2#include "Tree.h"
3#include "TreeCrxContextPreserved.h"
4#include <stack>
5
6
7namespace Tree
8{
9
11{
12 myGenotype_->registerParameter(state, "crx.context", (voidP) new double(0), ECF::DOUBLE);
13}
14
15
17{
18 voidP sptr = myGenotype_->getParameterValue(state, "crx.context");
19 probability_ = *((double*)sptr.get());
20 return true;
21}
22
23
24bool TreeCrxContextPreserved::mate(GenotypeP gen1, GenotypeP gen2, GenotypeP ch)
25{
26 Tree* male = (Tree*) (gen1.get());
27 Tree* female = (Tree*) (gen2.get());
28 Tree* child = (Tree*) (ch.get());
29
30 uint mRange, fRange;
31 uint mIndex, fIndex;
32 mRange = (uint) male->size();
33 fRange = (uint) female->size();
34
35 // create two vectors mapping the nodes with the same position in both trees (will also be at the same place in vector)
36 std::vector <uint> maleCommonIndexes;
37 std::vector <uint> femaleCommonIndexes;
38
39 // skip nodes that do not have context-dependant pair
40 std::stack <uint> maleSkip;
41 std::stack <uint> femaleSkip;
42
43 for(uint iMale = 0, iFemale = 0; iMale < mRange && iFemale < fRange; iMale++, iFemale++) {
44 // skip nodes in male parent
45 while (!maleSkip.empty() && iMale == maleSkip.top()) {
46 maleSkip.pop();
47 iMale += male->at(iMale)->size_;
48 }
49 if (iMale >= mRange) break;
50
51 // skip nodes in female parent
52 while (!femaleSkip.empty() && iFemale == femaleSkip.top()) {
53 femaleSkip.pop();
54 iFemale += female->at(iFemale)->size_;
55 }
56 if (iFemale >= fRange) break;
57
58 // denote context-paired nodes
59 maleCommonIndexes.push_back(iMale);
60 femaleCommonIndexes.push_back(iFemale);
61
62 uint maleArgNum = male->at(iMale)->primitive_->getNumberOfArguments();
63 uint femaleArgNum = female->at(iFemale)->primitive_->getNumberOfArguments();
64
65 if (maleArgNum > femaleArgNum) {
66
67 std::vector<uint> toSkip;
68
69 uint tmpIndex = iMale + 1;
70 for(uint i = 0; i < maleArgNum; i++) {
71 if (i >= femaleArgNum) toSkip.push_back(tmpIndex);
72 tmpIndex += male->at(tmpIndex)->size_;
73 }
74 // cvorove cija podstabla treba preskociti stavljamo na stog tako da je uvijek slijedeci na vrhu
75 for(int i = (int) toSkip.size() - 1; i >= 0; i--)
76 maleSkip.push(toSkip[i]);
77 }
78 if (maleArgNum < femaleArgNum) {
79
80 std::vector<uint> toSkip;
81
82 uint tmpIndex = iFemale + 1;
83 for(uint i = 0; i < femaleArgNum; i++) {
84 if (i >= maleArgNum) toSkip.push_back(tmpIndex);
85 tmpIndex += female->at(tmpIndex)->size_;
86 }
87 // cvorove cija podstabla treba preskociti stavljamo na stog tako da je uvijek slijedeci na vrhu
88 for(int i = (int) toSkip.size() - 1; i >= 0; i--)
89 femaleSkip.push(toSkip[i]);
90 }
91 }
92
93 if(maleCommonIndexes.empty()) {
94 ECF_LOG(state_, 5, "TreeCrxContextPreserved not successful.");
95 return false;
96 }
97
98 uint rndIndex = state_->getRandomizer()->getRandomInteger((uint)maleCommonIndexes.size());
99
100 mIndex = maleCommonIndexes[ rndIndex ];
101 fIndex = femaleCommonIndexes[ rndIndex ];
102
103 child->clear();
104
105 // copy from male parent
106 child->maxDepth_= male->maxDepth_;
107 child->minDepth_ = male->minDepth_;
108 child->startDepth_ = male->startDepth_;
109
110 // copy from male parent
111 for(uint i = 0; i < mIndex; i++) {
112 NodeP node = static_cast<NodeP> (new Node(male->at(i)->primitive_));
113 child->push_back(node);
114 child->at(i)->depth_ = male->at(i)->depth_;
115 }
116 // copy from female parent
117 for(uint i = 0; i < female->at( fIndex )->size_; i++) {
118 NodeP node = static_cast<NodeP> (new Node(female->at( fIndex + i)->primitive_));
119 child->push_back(node);
120 }
121 // copy rest from male parent
122 for(uint i = mIndex + male->at( mIndex )->size_; i < mRange; i++) {
123 NodeP node = static_cast<NodeP> (new Node( male->at(i)->primitive_));
124 child->push_back(node);
125 }
126
127 // update node depths and subtree sizes
128 child->update();
129
130 return true;
131}
132
133}
double probability_
probability of usage of this crossover operator
Definition: Crossover.h:42
GenotypeP myGenotype_
pointer to the Genotype that defines this CrossoverOp
Definition: Crossover.h:43
Node base class (Tree genotype)
Definition: Node.h:20
bool mate(GenotypeP gen1, GenotypeP gen2, GenotypeP child)
bool initialize(StateP)
Initialize crossover operator. Called before first crossover operation.
void registerParameters(StateP)
Register parameters with the system. Called before CrossoverOp::initialize.
Tree class - implements genotype as a tree.
Definition: Tree_c.h:29
Definition: nodes.h:92