00001 #include "../ECF_base.h"
00002 #include "Tree.h"
00003 #include <iostream>
00004 #include <sstream>
00005 #include <cmath>
00006 #include <sstream>
00007
00008
00009 #include "TreeMutPermutation.h"
00010 #include "TreeMutGauss.h"
00011 #include "TreeMutNodeReplace.h"
00012 #include "TreeMutNodeComplement.h"
00013 #include "TreeMutHoist.h"
00014 #include "TreeMutShrink.h"
00015 #include "TreeMutSubtree.h"
00016 #include "TreeCrxSimple.h"
00017 #include "TreeCrxUniform.h"
00018 #include "TreeCrxContextPreserved.h"
00019 #include "TreeCrxSizeFair.h"
00020 #include "TreeCrxOnePoint.h"
00021
00022
00023 namespace Tree
00024 {
00025
00026 Tree::Tree(void)
00027 {
00028 name_ = "Tree";
00029 startDepth_ = 0;
00030 }
00031
00032
00033 Tree::~Tree(void)
00034 { }
00035
00036
00037 Tree* Tree::copy()
00038 {
00039 Tree *newObject = new Tree(*this);
00040
00041
00042 for(int i = 0; i < (int) this->size(); i++) {
00043 (*newObject)[i] = (NodeP) (new Node((*this)[i]));
00044 }
00045 return newObject;
00046 }
00047
00048
00049 std::vector<CrossoverOpP> Tree::getCrossoverOp()
00050 {
00051 std::vector<CrossoverOpP> crx;
00052 crx.push_back((CrossoverOpP) (new TreeCrxSimple));
00053 crx.push_back((CrossoverOpP) (new TreeCrxContextPreserved));
00054 crx.push_back((CrossoverOpP) (new TreeCrxUniform));
00055 crx.push_back((CrossoverOpP) (new TreeCrxSizeFair));
00056 crx.push_back((CrossoverOpP) (new TreeCrxOnePoint));
00057 return crx;
00058 }
00059
00060
00061 std::vector<MutationOpP> Tree::getMutationOp()
00062 {
00063 std::vector<MutationOpP> mut;
00064 mut.push_back((MutationOpP) (new TreeMutPermutation));
00065 mut.push_back((MutationOpP) (new TreeMutGauss));
00066 mut.push_back((MutationOpP) (new TreeMutNodeReplace));
00067 mut.push_back((MutationOpP) (new TreeMutNodeComplement));
00068 mut.push_back((MutationOpP) (new TreeMutHoist));
00069 mut.push_back((MutationOpP) (new TreeMutShrink));
00070 mut.push_back((MutationOpP) (new TreeMutSubtree));
00071
00072 return mut;
00073 }
00074
00075
00080 bool Tree::addFunction(PrimitiveP func)
00081 {
00082 userFunctions_.push_back(func);
00083 return true;
00084 }
00085
00086
00091 bool Tree::addTerminal(PrimitiveP term)
00092 {
00093 userTerminals_.push_back(term);
00094 return true;
00095 }
00096
00097
00098 void Tree::registerParameters(StateP state)
00099 {
00100 registerParameter(state, "maxdepth", (voidP) (new uint(5)), ECF::UINT);
00101 registerParameter(state, "mindepth", (voidP) (new uint(1)), ECF::UINT);
00102 registerParameter(state, "initmaxdepth", (voidP) (new uint(5)), ECF::UINT);
00103 registerParameter(state, "initmindepth", (voidP) (new uint(1)), ECF::UINT);
00104 registerParameter(state, "functionset", (voidP) (new std::string), ECF::STRING);
00105 registerParameter(state, "terminalset", (voidP) (new std::string), ECF::STRING);
00106 }
00107
00108
00109 bool Tree::initialize(StateP state)
00110 {
00111
00112
00113 Tree* hometree = (Tree*) state->getGenotypes()[genotypeId_].get();
00114 state_ = state;
00115
00116
00117 if(!hometree->primitiveSet_)
00118 initializeFirst(hometree);
00119
00120
00121 this->primitiveSet_ = hometree->primitiveSet_;
00122 initMaxDepth_ = hometree->initMaxDepth_;
00123 initMinDepth_ = hometree->initMinDepth_;
00124 maxDepth_ = hometree->maxDepth_;
00125 minDepth_ = hometree->minDepth_;
00126
00127
00128 if(state->getRandomizer()->getRandomInteger(0, 1) % 2 == 0)
00129 fullBuild(primitiveSet_);
00130 else
00131 growBuild(primitiveSet_);
00132
00133 return true;
00134 }
00135
00136
00143 void Tree::initializeFirst(Tree* hometree)
00144 {
00145
00146 hometree->primitiveSet_ = (PrimitiveSetP) (new PrimitiveSet);
00147 hometree->primitiveSet_->initialize(state_);
00148 this->primitiveSet_ = hometree->primitiveSet_;
00149
00150
00151 for(int i = 0; i < (int) userFunctions_.size(); i++) {
00152 primitiveSet_->mAllPrimitives_[userFunctions_[i]->getName()] = userFunctions_[i];
00153 }
00154
00155
00156 voidP sptr = getParameterValue(state_, "functionset");
00157 std::stringstream names;
00158 std::string name;
00159 names << *((std::string*) sptr.get());
00160 while(names >> name) {
00161 if(!primitiveSet_->addFunction(name)) {
00162 ECF_LOG_ERROR(state_, "Error: unknown function in function set (\'" + name + "\')!");
00163 throw("");
00164 }
00165 }
00166 if(primitiveSet_->getFunctionSetSize() == 0) {
00167 ECF_LOG_ERROR(state_, "Tree genotype: empty function set!");
00168 throw("");
00169 }
00170
00171
00172 Primitives::terminal_type currentType = Primitives::Double;
00173 type_iter typeIter;
00174
00175
00176 std::stringstream tNames;
00177 sptr = getParameterValue(state_, "terminalset");
00178 tNames << *((std::string*) sptr.get());
00179
00180 while(tNames >> name)
00181 {
00182
00183 typeIter = primitiveSet_->mTypeNames_.find(name);
00184 if(typeIter != primitiveSet_->mTypeNames_.end()) {
00185 currentType = typeIter->second;
00186 continue;
00187 }
00188
00189
00190 uint iTerminal = 0;
00191 for(; iTerminal < userTerminals_.size(); iTerminal++)
00192 if(userTerminals_[iTerminal]->getName() == name)
00193 break;
00194 if(iTerminal < userTerminals_.size()) {
00195 primitiveSet_->addTerminal(userTerminals_[iTerminal]);
00196 continue;
00197 }
00198
00199
00200
00201
00202 if(name[0] == '[' || name[0] == '{') {
00203
00204 std::string ercValues = "";
00205
00206
00207 PrimitiveP erc;
00208 switch(currentType) {
00209 case Primitives::Double:
00210 erc = (PrimitiveP) (new Primitives::ERCD);
00211 ercValues = DBL_PREFIX;
00212 break;
00213 case Primitives::Int:
00214 erc = (PrimitiveP) (new Primitives::ERC<int>);
00215 ercValues = INT_PREFIX;
00216 break;
00217 case Primitives::Bool:
00218 erc = (PrimitiveP) (new Primitives::ERC<bool>);
00219 ercValues = BOOL_PREFIX;
00220 break;
00221 case Primitives::Char:
00222 erc = (PrimitiveP) (new Primitives::ERC<char>);
00223 ercValues = CHR_PREFIX;
00224 break;
00225 case Primitives::String:
00226 erc = (PrimitiveP) (new Primitives::ERC<std::string>);
00227 ercValues = STR_PREFIX;
00228 break;
00229 }
00230
00231 while(name[name.size() - 1] != ']' && name[name.size() - 1] != '}') {
00232 ercValues += " " + name;
00233 tNames >> name;
00234 }
00235 ercValues += " " + name;
00236
00237
00238 erc->setName(ercValues);
00239 erc->initialize(state_);
00240 primitiveSet_->addTerminal(erc);
00241
00242 continue;
00243 }
00244
00245
00246
00247 PrimitiveP terminal;
00248 switch(currentType)
00249 {
00250 case Primitives::Double:
00251 terminal = (PrimitiveP) (new Primitives::Terminal); break;
00252 case Primitives::Int:
00253 terminal = (PrimitiveP) (new Primitives::TerminalT<int>); break;
00254 case Primitives::Bool:
00255 terminal = (PrimitiveP) (new Primitives::TerminalT<bool>); break;
00256 case Primitives::Char:
00257 terminal = (PrimitiveP) (new Primitives::TerminalT<char>); break;
00258 case Primitives::String:
00259 terminal = (PrimitiveP) (new Primitives::TerminalT<std::string>); break;
00260 }
00261
00262
00263
00264 std::istringstream ss(name);
00265 switch(currentType)
00266 {
00267 case Primitives::Double:
00268 double dblValue;
00269 ss >> dblValue;
00270 if(ss.fail() == false)
00271 terminal->setValue(&dblValue);
00272 break;
00273 case Primitives::Int:
00274 int intValue;
00275 ss >> intValue;
00276 if(ss.fail() == false)
00277 terminal->setValue(&intValue);
00278 break;
00279 case Primitives::Bool:
00280 bool boolValue;
00281 ss >> boolValue;
00282 if(name == "true")
00283 boolValue = true;
00284 else if(name == "false")
00285 boolValue = false;
00286 if(ss.fail() == false || name == "true" || name == "false") {
00287 if(boolValue)
00288 name = "true";
00289 else
00290 name = "false";
00291 terminal->setValue(&boolValue);
00292 }
00293 break;
00294 case Primitives::Char:
00295 char charValue;
00296 ss >> charValue;
00297 if(ss.fail() == false)
00298 terminal->setValue(&charValue);
00299 break;
00300 case Primitives::String:
00301 std::string stringValue;
00302 ss >> stringValue;
00303 if(ss.fail() == false)
00304 terminal->setValue(&stringValue);
00305 break;
00306 }
00307 terminal->setName(name);
00308 primitiveSet_->addTerminal(terminal);
00309
00310 }
00311
00312 if(primitiveSet_->getTerminalSetSize() == 0) {
00313 ECF_LOG_ERROR(state_, "Tree: Empty terminal set!");
00314 throw("");
00315 }
00316
00317
00318 sptr = getParameterValue(state_, "maxdepth");
00319 hometree->maxDepth_ = *((uint*) sptr.get());
00320 sptr = getParameterValue(state_, "mindepth");
00321 hometree->minDepth_ = *((uint*) sptr.get());
00322 if(hometree->maxDepth_ < hometree->minDepth_ || hometree->maxDepth_ < 1) {
00323 ECF_LOG_ERROR(state_, "Tree genotype: invalid values for max and min tree depth!");
00324 throw("");
00325 }
00326
00327 hometree->initMaxDepth_ = hometree->maxDepth_;
00328 if(isParameterDefined(state_, "initmaxdepth")) {
00329 sptr = getParameterValue(state_, "initmaxdepth");
00330 hometree->initMaxDepth_ = *((uint*) sptr.get());
00331 }
00332 hometree->initMinDepth_ = hometree->minDepth_;
00333 if(isParameterDefined(state_, "initmindepth")) {
00334 sptr = getParameterValue(state_, "initmindepth");
00335 hometree->initMinDepth_ = *((uint*) sptr.get());
00336 }
00337 if(hometree->initMaxDepth_ < hometree->initMinDepth_ || hometree->initMaxDepth_ < 1) {
00338 ECF_LOG_ERROR(state_, "Tree genotype: invalid values for initial max and min tree depth!");
00339 throw("");
00340 }
00341 if(hometree->initMaxDepth_ > hometree->maxDepth_) {
00342 ECF_LOG_ERROR(state_, "Tree genotype: initial max depth cannot be greater than evolution max depth!");
00343 throw("");
00344 }
00345 }
00346
00347
00354 void Tree::execute(void *result)
00355 {
00356 iNode_ = 0;
00357 this->at(iNode_)->primitive_->execute(result, *this);
00358 }
00359
00360
00361 void Tree::addNode(Node *node)
00362 {
00363 this->push_back(static_cast<NodeP> (node));
00364 }
00365
00366
00367 void Tree::addNode(NodeP node)
00368 {
00369 this->push_back(node);
00370 }
00371
00372
00374 uint Tree::fullBuild(PrimitiveSetP primitiveSet, int myDepth)
00375 {
00376 Node* node = new Node();
00377 node->depth_ = myDepth;
00378
00379 if(node->depth_ < this->initMaxDepth_) {
00380 node->setPrimitive(primitiveSet->getRandomFunction());
00381 this->addNode(node);
00382 } else {
00383 node->setPrimitive(primitiveSet->getRandomTerminal());
00384 this->addNode(node);
00385 }
00386
00387 for(int i = 0; i < node->primitive_->getNumberOfArguments(); i++ ) {
00388 node->size_ += fullBuild(primitiveSet, myDepth + 1);
00389 }
00390
00391 return node->size_;
00392 }
00393
00394
00396 uint Tree::growBuild(PrimitiveSetP primitiveSet, int myDepth)
00397 {
00398 Node* node = new Node();
00399 node->depth_ = myDepth;
00400
00401 if(node->depth_ < this->initMinDepth_) {
00402 node->setPrimitive(primitiveSet->getRandomFunction());
00403 this->addNode(node);
00404 }
00405 else if(node->depth_ < this->initMaxDepth_) {
00406 node->setPrimitive(primitiveSet->getRandomPrimitive());
00407 this->addNode(node);
00408 }
00409 else {
00410 node->setPrimitive(primitiveSet->getRandomTerminal());
00411 this->addNode(node);
00412 }
00413
00414 for(int i = 0; i < node->primitive_->getNumberOfArguments(); i++) {
00415 node->size_ += growBuild(primitiveSet, myDepth + 1);
00416 }
00417
00418 return node->size_;
00419 }
00420
00421
00427 void Tree::update()
00428 {
00429 this->at(0)->size_ = setSize(0);
00430
00431 iNode_ = 0;
00432 for(int i = 0; i < this->at(0)->primitive_->getNumberOfArguments(); i++) {
00433 iNode_++;
00434 setDepth(startDepth_ + 1);
00435 }
00436 this->at(0)->depth_ = startDepth_;
00437 }
00438
00439
00443 uint Tree::setSize(int iNode)
00444 {
00445 int myNode = iNode;
00446 int mySize = 1;
00447 for(int i = 0; i < this->at(myNode)->primitive_->getNumberOfArguments(); i++) {
00448 int childSize = setSize(iNode + 1);
00449 mySize += childSize;
00450 iNode += childSize;
00451 }
00452 this->at(myNode)->size_ = mySize;
00453 return mySize;
00454 }
00455
00456
00460 void Tree::setDepth(int myDepth)
00461 {
00462 int index = iNode_;
00463 int nArgs = this->at( iNode_ )->primitive_->getNumberOfArguments();
00464 for(int i = 0; i < nArgs; i++) {
00465 iNode_++;
00466 setDepth(myDepth + 1);
00467 }
00468 this->at(index)->depth_ = myDepth;
00469 }
00470
00471
00475 void Tree::growBuild(PrimitiveSetP primitiveSet)
00476 {
00477 growBuild(primitiveSet, startDepth_);
00478 }
00479
00480
00484 void Tree::fullBuild(PrimitiveSetP primitiveSet)
00485 {
00486 fullBuild(primitiveSet, startDepth_);
00487 }
00488
00489
00496 void Tree::setTerminalValue(std::string name, void* value)
00497 {
00498 PrimitiveP term = primitiveSet_->getTerminalByName(name);
00499 if(term == PrimitiveP()) {
00500 ECF_LOG_ERROR(state_, "Tree genotype: invalid terminal name referenced in setTerminalValue()!");
00501 throw("");
00502 }
00503
00504 term->setValue(value);
00505 }
00506
00507
00508 void Tree::write(XMLNode& xTree)
00509 {
00510 xTree = XMLNode::createXMLTopNode("Tree");
00511 std::stringstream sValue;
00512 sValue << this->size();
00513 xTree.addAttribute("size", sValue.str().c_str());
00514
00515 sValue.str("");
00516 for(uint i = 0; i < this->size(); i++) {
00517 sValue << this->at(i)->primitive_->getName() << " ";
00518 }
00519 xTree.addText(sValue.str().c_str());
00520 }
00521
00522
00523 void Tree::read(XMLNode& xTree)
00524 {
00525 this->clear();
00526
00527 XMLCSTR sizeStr = xTree.getAttribute("size");
00528 uint size = str2uint(sizeStr);
00529
00530 XMLCSTR tree = xTree.getText();
00531 std::stringstream stream;
00532 stream << tree;
00533
00534 std::vector<PrimitiveP>& primitives = primitiveSet_->primitives_;
00535 std::string primitiveStr;
00536 uint position = 0;
00537
00538 for(uint iNode = 0; iNode < size; iNode++) {
00539 stream >> primitiveStr;
00540 Node* node = new Node();
00541
00542
00543 PrimitiveP prim = primitiveSet_->getPrimitiveByName(primitiveStr);
00544 if(prim != PrimitiveP()) {
00545 node->setPrimitive(prim);
00546 this->addNode(node);
00547 continue;
00548 }
00549
00550
00551
00552 PrimitiveP erc;
00553 std::string prefix = primitiveStr.substr(0, 2);
00554 std::string value = primitiveStr.substr(2);
00555 std::stringstream ss;
00556 ss << value;
00557 if(prefix == DBL_PREFIX) {
00558 erc = (PrimitiveP) (new Primitives::ERCD);
00559 double v;
00560 ss >> v;
00561 erc->setValue(&v);
00562 }
00563 else if(prefix == INT_PREFIX) {
00564 erc = (PrimitiveP) (new Primitives::ERC<int>);
00565 int v;
00566 ss >> v;
00567 erc->setValue(&v);
00568 }
00569 else if(prefix == INT_PREFIX) {
00570 erc = (PrimitiveP) (new Primitives::ERC<int>);
00571 int v;
00572 ss >> v;
00573 erc->setValue(&v);
00574 }
00575 else if(prefix == BOOL_PREFIX) {
00576 erc = (PrimitiveP) (new Primitives::ERC<bool>);
00577 bool v;
00578 ss >> v;
00579 erc->setValue(&v);
00580 }
00581 else if(prefix == CHR_PREFIX) {
00582 erc = (PrimitiveP) (new Primitives::ERC<char>);
00583 char v;
00584 ss >> v;
00585 erc->setValue(&v);
00586 }
00587 else if(prefix == STR_PREFIX) {
00588 erc = (PrimitiveP) (new Primitives::ERC<std::string>);
00589 std::string v;
00590 ss >> v;
00591 erc->setValue(&v);
00592 }
00593 else {
00594 ECF_LOG_ERROR(state_, "Tree genotype: undefined primitive (" + primitiveStr + ")!");
00595 throw("");
00596 }
00597 erc->setName(primitiveStr);
00598 node->primitive_ = erc;
00599 this->addNode(node);
00600 }
00601
00602
00603 this->update();
00604 }
00605
00606 }