00001 #include "../ECF_base.h"
00002 #include "Tree.h"
00003 #include "TreeMutPermutation.h"
00004 #include <stdio.h>
00005
00006
00007 namespace Tree
00008 {
00009
00010 void TreeMutPermutation::registerParameters(StateP state)
00011 {
00012 myGenotype_->registerParameter(state, "mut.permutation", (voidP) new double(0), ECF::DOUBLE);
00013 }
00014
00015
00016 bool TreeMutPermutation::initialize(StateP state)
00017 {
00018 voidP sptr = myGenotype_->getParameterValue(state, "mut.permutation");
00019 probability_ = *((double*)sptr.get());
00020 return true;
00021 }
00022
00023
00024 bool TreeMutPermutation::mutate(GenotypeP gene)
00025 {
00026 Tree* tree = (Tree*) (gene.get());
00027
00028
00029 uint iNode, nArgs;
00030 uint tries = 0;
00031 do {
00032 iNode = state_->getRandomizer()->getRandomInteger((int) tree->size());
00033 tries++;
00034 } while((nArgs = tree->at(iNode)->primitive_->getNumberOfArguments()) < 2 && tries < 4);
00035
00036 if(nArgs < 2)
00037 return false;
00038
00039
00040 std::vector<uint> permutation;
00041 permutation.resize(nArgs);
00042
00043 for(uint i = 0; i < nArgs; i++) {
00044 permutation[i] = i;
00045 }
00046 uint ind1, ind2, temp;
00047 for(uint i = 0; i < nArgs - 1; i++) {
00048 ind1 = permutation[i];
00049 ind2 = state_->getRandomizer()->getRandomInteger(i, nArgs - 1);
00050 temp = permutation[ind1];
00051 permutation[ind1] = permutation[ind2];
00052 permutation[ind2] = temp;
00053 }
00054
00055
00056 std::vector<uint> offsets;
00057 offsets.push_back(1);
00058 for(uint i = 1; i < nArgs; i++) {
00059 offsets.push_back(offsets[i - 1] + tree->at(iNode + offsets[i - 1])->size_);
00060 }
00061
00062
00063 std::vector<NodeP> mutNodes;
00064 mutNodes.assign(tree->begin() + iNode, tree->begin() + iNode + tree->at(iNode)->size_);
00065
00066 uint iCopiedTo = 1;
00067 for(uint iArg = 0; iArg < nArgs; iArg++) {
00068 uint nNodes = mutNodes[offsets[permutation[iArg]]]->size_;
00069 for(uint i = 0; i < nNodes; i++, iCopiedTo++) {
00070 tree->at(iNode + iCopiedTo) = mutNodes[offsets[permutation[iArg]] + i];
00071 }
00072 }
00073
00074 return true;
00075 }
00076
00077 }