• Main Page
  • Modules
  • Classes
  • Files
  • File List

D:/Projekt/ECF_trunk/ECF/tree/TreeMutSubtree.cpp

00001 #include "../ECF_base.h"
00002 #include "Tree.h"
00003 #include "TreeMutSubtree.h"
00004 #include <stdio.h>
00005 
00006 
00007 namespace Tree
00008 {
00009 
00010 void TreeMutSubtree::registerParameters(StateP state)
00011 {
00012     myGenotype_->registerParameter(state, "mut.subtree", (voidP) new double(0), ECF::DOUBLE);
00013 }
00014 
00015 
00016 bool TreeMutSubtree::initialize(StateP state)
00017 {
00018     voidP sptr = myGenotype_->getParameterValue(state, "mut.subtree");
00019     probability_ = *((double*)sptr.get());
00020     return true;
00021 }
00022 
00023 
00024 bool TreeMutSubtree::mutate(GenotypeP gene)
00025 {
00026     Tree* tree = (Tree*) (gene.get());
00027 
00028     // try to select random node in tree which is not a terminal and which is not on maxDepth
00029     // this is a size-fair operator (depth condition)
00030     uint chosenNode;
00031     uint chosenNodeSubtreeSize;
00032     uint chosenNodeDepth;
00033     uint tries = 0;
00034     do {
00035         chosenNode = state_->getRandomizer()->getRandomInteger((int) tree->size());
00036         chosenNodeSubtreeSize = tree->at(chosenNode)->size_;
00037         chosenNodeDepth = tree->at(chosenNode)->depth_;
00038         tries++;
00039     } while((/*chosenNodeSubtreeSize == 1 || */chosenNodeDepth == tree->maxDepth_) && tries < 4);
00040 
00041     if(tries == 4) {
00042         ECF_LOG(state_, 5, "TreeMutSubtree not successful.");
00043         return false;
00044     }
00045 
00046     // first of all, make a copy of tree and clear the original
00047     Tree* copyTree = tree->copy();
00048     tree->clear();
00049 
00050     std::stringstream log;
00051     log << "TreeMutSubtree successful (";
00052 
00053     uint i = 0;
00054 
00055     // copy all nodes before chosen subtree to original
00056     for( ; i < chosenNode; i++) {
00057         NodeP node = static_cast<NodeP> (new Node(copyTree->at(i)->primitive_));
00058         tree->addNode(node);
00059     }
00060 
00061     log << "mutatedSubtree(at depth " << chosenNodeDepth << ") = ";
00062     for( ; i < chosenNode + chosenNodeSubtreeSize; i++) {
00063         // this node is an element of the chosen subtree
00064         log << copyTree->at(i)->primitive_->getName() << " ";
00065     }
00066 
00067     // generate new subtree with same primitives as original tree
00068     // maxDepth for that new tree is original tree->maxDepth_ - chosenNodeDepth
00069     Tree* newTree = tree->copy();
00070     newTree->clear();
00071     newTree->initMinDepth_ = 0;
00072     newTree->initMaxDepth_ = copyTree->maxDepth_ - chosenNodeDepth;
00073 
00074     if(state_->getRandomizer()->getRandomInteger(0, 1) % 2 == 0)
00075         newTree->fullBuild(copyTree->primitiveSet_);
00076     else
00077         newTree->growBuild(copyTree->primitiveSet_);
00078 
00079     log << ", newSubtree = ";
00080     // copy all nodes from newTree to tree
00081     for(uint j = 0; j < newTree->size(); j++) {
00082         NodeP node = static_cast<NodeP> (new Node(newTree->at(j)->primitive_));
00083         tree->addNode(node);
00084         log << node->primitive_->getName() << " ";
00085     }
00086     log << ")";
00087 
00088     // copy all nodes after chosen subtree to original
00089     for( ; i < copyTree->size(); i++) {
00090         NodeP node = static_cast<NodeP> (new Node(copyTree->at(i)->primitive_));
00091         tree->addNode(node);
00092     }
00093 
00094     tree->update();
00095     delete copyTree;
00096     delete newTree;
00097 
00098     ECF_LOG(state_, 5, log.str());
00099 
00100     return true;
00101 }
00102 
00103 }

Generated on Tue Nov 4 2014 13:04:31 for ECF by  doxygen 1.7.1