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
00081 bool Tree::addFunction(PrimitiveP func)
00082 {
00083 userFunctions_.push_back(func);
00084 return true;
00085 }
00086
00087
00093 bool Tree::addTerminal(PrimitiveP term)
00094 {
00095 userTerminals_.push_back(term);
00096 return true;
00097 }
00098
00099
00100 void Tree::registerParameters(StateP state)
00101 {
00102 registerParameter(state, "maxdepth", (voidP) (new uint(5)), ECF::UINT);
00103 registerParameter(state, "mindepth", (voidP) (new uint(1)), ECF::UINT);
00104 registerParameter(state, "initmaxdepth", (voidP) (new uint(5)), ECF::UINT);
00105 registerParameter(state, "initmindepth", (voidP) (new uint(1)), ECF::UINT);
00106 registerParameter(state, "functionset", (voidP) (new std::string), ECF::STRING);
00107 registerParameter(state, "terminalset", (voidP) (new std::string), ECF::STRING);
00108 }
00109
00110
00111 bool Tree::initialize(StateP state)
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 if(state->getRandomizer()->getRandomInteger(0, 1) % 2 == 0)
00128 fullBuild(primitiveSet_);
00129 else
00130 growBuild(primitiveSet_);
00131
00132 return true;
00133 }
00134
00135
00140 void Tree::initializeFirst(Tree* hometree)
00141 {
00142 hometree->primitiveSet_ = (PrimitiveSetP) (new PrimitiveSet);
00143 hometree->primitiveSet_->initialize(state_);
00144 this->primitiveSet_ = hometree->primitiveSet_;
00145
00146
00147 for(int i = 0; i < (int) userFunctions_.size(); i++) {
00148 primitiveSet_->mPrimitives_[userFunctions_[i]->getName()] = userFunctions_[i];
00149 }
00150
00151 voidP sptr = getParameterValue(state_, "functionset");
00152 std::stringstream names;
00153 std::string name;
00154 names << *((std::string*) sptr.get());
00155 while(names >> name) {
00156 if(!primitiveSet_->addFunction(name)) {
00157 state_->getLogger()->log(1, "Error: unknown function in function set (\'" + name + "\')!");
00158 throw("");
00159 }
00160 }
00161 if(primitiveSet_->getFunctionSetSize() == 0) {
00162 state_->getLogger()->log(1, "Tree genotype: empty function set!");
00163 throw("");
00164 }
00165
00166 Primitives::terminal_type currentType = Primitives::Double;
00167 type_iter typeIter;
00168
00169 std::stringstream tNames;
00170 sptr = getParameterValue(state_, "terminalset");
00171 tNames << *((std::string*) sptr.get());
00172
00173 while(tNames >> name)
00174 {
00175
00176 typeIter = primitiveSet_->mTypeNames_.find(name);
00177 if(typeIter != primitiveSet_->mTypeNames_.end()) {
00178 currentType = typeIter->second;
00179 continue;
00180 }
00181
00182
00183 uint iTerminal = 0;
00184 for(; iTerminal < userTerminals_.size(); iTerminal++)
00185 if(userTerminals_[iTerminal]->getName() == name)
00186 break;
00187 if(iTerminal < userTerminals_.size()) {
00188 primitiveSet_->addTerminal(userTerminals_[iTerminal]);
00189 continue;
00190 }
00191
00192
00193
00194 if(name[0] == '[' || name[0] == '{') {
00195
00196 std::string ercValues = "";
00197
00198 PrimitiveP erc;
00199 switch(currentType) {
00200 case Primitives::Double:
00201 erc = (PrimitiveP) (new Primitives::ERCD);
00202 ercValues = DBL_PREFIX;
00203 break;
00204 case Primitives::Int:
00205 erc = (PrimitiveP) (new Primitives::ERC<int>);
00206 ercValues = INT_PREFIX;
00207 break;
00208 case Primitives::Bool:
00209 erc = (PrimitiveP) (new Primitives::ERC<bool>);
00210 ercValues = BOOL_PREFIX;
00211 break;
00212 case Primitives::Char:
00213 erc = (PrimitiveP) (new Primitives::ERC<char>);
00214 ercValues = CHR_PREFIX;
00215 break;
00216 case Primitives::String:
00217 erc = (PrimitiveP) (new Primitives::ERC<std::string>);
00218 ercValues = STR_PREFIX;
00219 break;
00220 }
00221
00222 while(name[name.size() - 1] != ']' && name[name.size() - 1] != '}') {
00223 ercValues += " " + name;
00224 tNames >> name;
00225 }
00226 ercValues += " " + name;
00227
00228
00229 erc->setName(ercValues);
00230 erc->initialize(state_);
00231 primitiveSet_->addTerminal(erc);
00232
00233 continue;
00234 }
00235
00236
00237
00238 PrimitiveP terminal;
00239 switch(currentType)
00240 {
00241 case Primitives::Double:
00242 terminal = (PrimitiveP) (new Primitives::Terminal); break;
00243 case Primitives::Int:
00244 terminal = (PrimitiveP) (new Primitives::TerminalT<int>); break;
00245 case Primitives::Bool:
00246 terminal = (PrimitiveP) (new Primitives::TerminalT<bool>); break;
00247 case Primitives::Char:
00248 terminal = (PrimitiveP) (new Primitives::TerminalT<char>); break;
00249 case Primitives::String:
00250 terminal = (PrimitiveP) (new Primitives::TerminalT<std::string>); break;
00251 }
00252
00253
00254
00255
00256 std::istringstream ss(name);
00257 switch(currentType)
00258 {
00259 case Primitives::Double:
00260 double dblValue;
00261 ss >> dblValue;
00262 if(ss.fail() == false)
00263 terminal->setValue(&dblValue);
00264 break;
00265 case Primitives::Int:
00266 int intValue;
00267 ss >> intValue;
00268 if(ss.fail() == false)
00269 terminal->setValue(&intValue);
00270 break;
00271 case Primitives::Bool:
00272 bool boolValue;
00273 ss >> boolValue;
00274 if(name == "true")
00275 boolValue = true;
00276 else if(name == "false")
00277 boolValue = false;
00278 if(ss.fail() == false || name == "true" || name == "false") {
00279 if(boolValue)
00280 name = "true";
00281 else
00282 name = "false";
00283 terminal->setValue(&boolValue);
00284 }
00285 break;
00286 case Primitives::Char:
00287 char charValue;
00288 ss >> charValue;
00289 if(ss.fail() == false)
00290 terminal->setValue(&charValue);
00291 break;
00292 case Primitives::String:
00293 std::string stringValue;
00294 ss >> stringValue;
00295 if(ss.fail() == false)
00296 terminal->setValue(&stringValue);
00297 break;
00298 }
00299 terminal->setName(name);
00300 primitiveSet_->addTerminal(terminal);
00301
00302 }
00303
00304
00305 if(primitiveSet_->getTerminalSetSize() == 0) {
00306 state_->getLogger()->log(1, "Tree: Empty terminal set!");
00307 throw("");
00308 }
00309
00310
00311 sptr = getParameterValue(state_, "maxdepth");
00312 hometree->maxDepth_ = *((uint*) sptr.get());
00313 sptr = getParameterValue(state_, "mindepth");
00314 hometree->minDepth_ = *((uint*) sptr.get());
00315 if(hometree->maxDepth_ < hometree->minDepth_ || hometree->maxDepth_ < 1) {
00316 state_->getLogger()->log(1, "Tree genotype: invalid values for max and min tree depth!");
00317 throw("");
00318 }
00319
00320 hometree->initMaxDepth_ = hometree->maxDepth_;
00321 if(isParameterDefined(state_, "initmaxdepth")) {
00322 sptr = getParameterValue(state_, "initmaxdepth");
00323 hometree->initMaxDepth_ = *((uint*) sptr.get());
00324 }
00325 hometree->initMinDepth_ = hometree->minDepth_;
00326 if(isParameterDefined(state_, "initmindepth")) {
00327 sptr = getParameterValue(state_, "initmindepth");
00328 hometree->initMinDepth_ = *((uint*) sptr.get());
00329 }
00330 if(hometree->initMaxDepth_ < hometree->initMinDepth_ || hometree->initMaxDepth_ < 1) {
00331 state_->getLogger()->log(1, "Tree genotype: invalid values for initial max and min tree depth!");
00332 throw("");
00333 }
00334 if(hometree->initMaxDepth_ > hometree->maxDepth_) {
00335 state_->getLogger()->log(1, "Tree genotype: initial max depth cannot be greater than evolution max depth!");
00336 throw("");
00337 }
00338 }
00339
00340
00347 void Tree::execute(void *result)
00348 {
00349 iNode_ = 0;
00350 this->at(iNode_)->primitive_->execute(result, *this);
00351 }
00352
00353
00354 void Tree::addNode(Node *node)
00355 {
00356 this->push_back(static_cast<NodeP> (node));
00357 }
00358
00359
00360 void Tree::addNode(NodeP node)
00361 {
00362 this->push_back(node);
00363 }
00364
00365
00366 uint Tree::fullBuild(PrimitiveSetP primitiveSet, int myDepth)
00367 {
00368 Node* node = new Node();
00369 node->depth_ = myDepth;
00370
00371 if(node->depth_ < this->initMaxDepth_) {
00372 node->setPrimitive(primitiveSet->getRandomFunction());
00373 this->addNode(node);
00374 } else {
00375 node->setPrimitive(primitiveSet->getRandomTerminal());
00376 this->addNode(node);
00377 }
00378
00379 for(int i = 0; i < node->primitive_->getNumberOfArguments(); i++ ) {
00380 node->size_ += fullBuild(primitiveSet, myDepth + 1);
00381 }
00382
00383 return node->size_;
00384 }
00385
00386
00387 uint Tree::growBuild(PrimitiveSetP primitiveSet, int myDepth)
00388 {
00389 Node* node = new Node();
00390 node->depth_ = myDepth;
00391
00392 if(node->depth_ < this->initMinDepth_) {
00393 node->setPrimitive(primitiveSet->getRandomFunction());
00394 this->addNode(node);
00395 }
00396 else if(node->depth_ < this->initMaxDepth_) {
00397 node->setPrimitive(primitiveSet->getRandomPrimitive());
00398 this->addNode(node);
00399 }
00400 else {
00401 node->setPrimitive(primitiveSet->getRandomTerminal());
00402 this->addNode(node);
00403 }
00404
00405 for(int i = 0; i < node->primitive_->getNumberOfArguments(); i++) {
00406 node->size_ += growBuild(primitiveSet, myDepth + 1);
00407 }
00408
00409 return node->size_;
00410 }
00411
00412
00418 void Tree::update()
00419 {
00420 this->at(0)->size_ = setSize(0);
00421
00422 iNode_ = 0;
00423 for(int i = 0; i < this->at(0)->primitive_->getNumberOfArguments(); i++) {
00424 iNode_++;
00425 setDepth(startDepth_ + 1);
00426 }
00427 this->at(0)->depth_ = startDepth_;
00428 }
00429
00430
00434 uint Tree::setSize(int iNode)
00435 {
00436 int myNode = iNode;
00437 int mySize = 1;
00438 for(int i = 0; i < this->at(myNode)->primitive_->getNumberOfArguments(); i++) {
00439 int childSize = setSize(iNode + 1);
00440 mySize += childSize;
00441 iNode += childSize;
00442 }
00443 this->at(myNode)->size_ = mySize;
00444 return mySize;
00445 }
00446
00447
00451 void Tree::setDepth(int myDepth)
00452 {
00453 int index = iNode_;
00454 int nArgs = this->at( iNode_ )->primitive_->getNumberOfArguments();
00455 for(int i = 0; i < nArgs; i++) {
00456 iNode_++;
00457 setDepth( myDepth + 1);
00458 }
00459 this->at(index)->depth_ = myDepth;
00460 }
00461
00462
00466 void Tree::growBuild(PrimitiveSetP primitiveSet)
00467 {
00468 growBuild(primitiveSet, startDepth_);
00469 }
00470
00471
00475 void Tree::fullBuild(PrimitiveSetP primitiveSet)
00476 {
00477 fullBuild(primitiveSet, startDepth_);
00478 }
00479
00480
00487 void Tree::setTerminalValue(std::string name, void* value)
00488 {
00489 uint termIndex;
00490 for(termIndex = 0; termIndex < primitiveSet_->terminalSet_.size(); termIndex++) {
00491 if(name == primitiveSet_->terminalSet_.at(termIndex)->getName()) {
00492 break;
00493 }
00494 }
00495
00496 if(termIndex == primitiveSet_->terminalSet_.size()) {
00497 state_->getLogger()->log(1, "Tree genotype: invalid terminal name referenced in setTerminalValue()!");
00498 throw("");
00499 }
00500
00501 primitiveSet_->terminalSet_.at(termIndex)->setValue(value);
00502 }
00503
00504
00505 void Tree::write(XMLNode& xTree)
00506 {
00507 xTree = XMLNode::createXMLTopNode("Tree");
00508 std::stringstream sValue;
00509 sValue << this->size();
00510 xTree.addAttribute("size", sValue.str().c_str());
00511
00512 sValue.str("");
00513 for(uint i = 0; i < this->size(); i++) {
00514 sValue << this->at(i)->primitive_->getName() << " ";
00515 }
00516 xTree.addText(sValue.str().c_str());
00517 }
00518
00519
00520 void Tree::read(XMLNode& xTree)
00521 {
00522 this->clear();
00523
00524 XMLCSTR sizeStr = xTree.getAttribute("size");
00525 uint size = str2uint(sizeStr);
00526
00527 XMLCSTR tree = xTree.getText();
00528 std::stringstream stream;
00529 stream << tree;
00530
00531 std::vector<PrimitiveP>& primitives = primitiveSet_->primitives_;
00532 std::string primitiveStr;
00533 uint position = 0;
00534
00535 for(uint iNode = 0; iNode < size; iNode++) {
00536 stream >> primitiveStr;
00537 Node* node = new Node();
00538 uint iPrim;
00539
00540
00541 for(iPrim = 0; iPrim < primitiveSet_->primitives_.size(); iPrim++)
00542 if(primitives[iPrim]->getName() == primitiveStr) {
00543 node->setPrimitive(primitives[iPrim]);
00544 this->addNode(node);
00545 break;
00546 }
00547 if(iPrim != primitiveSet_->primitives_.size())
00548 continue;
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 state_->getLogger()->log(1, "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 }