/*! * \brief Exchange two GP trees on given points. * \param ioTree1 First tree to mate. * \param inNode1 Node index of the swap subtree first point. * \param ioContext1 Evolutionary context relatively to the first tree. * \param ioTree2 Second tree to mate. * \param inNode2 Node index of the swap subtree second point. * \param ioContext2 Evolutionary context relatively to the second tree. */ void GP::MutationSwapSubtreeOp::exchangeSubTrees(GP::Tree& ioTree1, unsigned int inNode1, GP::Context& ioContext1, GP::Tree& ioTree2, unsigned int inNode2, GP::Context& ioContext2) { Beagle_StackTraceBeginM(); Beagle_AssertM(&ioTree1 != &ioTree2); unsigned int lSwapSize1 = ioTree1[inNode1].mSubTreeSize; unsigned int lSwapSize2 = ioTree2[inNode2].mSubTreeSize; if(lSwapSize1 <= lSwapSize2) { std::swap_ranges(ioTree1.begin()+inNode1, ioTree1.begin()+inNode1+lSwapSize1, ioTree2.begin()+inNode2); ioTree1.insert(ioTree1.begin()+inNode1+lSwapSize1, ioTree2.begin()+inNode2+lSwapSize1, ioTree2.begin()+inNode2+lSwapSize2); ioTree2.erase(ioTree2.begin()+inNode2+lSwapSize1, ioTree2.begin()+inNode2+lSwapSize2); } else { std::swap_ranges(ioTree1.begin()+inNode1, ioTree1.begin()+inNode1+lSwapSize2, ioTree2.begin()+inNode2); ioTree2.insert(ioTree2.begin()+inNode2+lSwapSize2, ioTree1.begin()+inNode1+lSwapSize2, ioTree1.begin()+inNode1+lSwapSize1); ioTree1.erase(ioTree1.begin()+inNode1+lSwapSize2, ioTree1.begin()+inNode1+lSwapSize1); } int lDiffSize = lSwapSize1 - lSwapSize2; for(unsigned int i=0; i<(ioContext1.getCallStackSize()-1); i++) ioTree1[ioContext1.getCallStackElement(i)].mSubTreeSize -= lDiffSize; for(unsigned int j=0; j<(ioContext2.getCallStackSize()-1); j++) ioTree2[ioContext2.getCallStackElement(j)].mSubTreeSize += lDiffSize; Beagle_StackTraceEndM(); }
/*! * \brief Expand given module of a GP tree. * \param inNodeToExpand Index of node to expand in GP tree. * \param ioTree Tree from which module will be expanded. * \param ioContext Evolutionary context. */ void GP::ModuleExpandOp::expand(unsigned int inNodeToExpand, GP::Tree& ioTree, GP::Context& ioContext) { Beagle_StackTraceBeginM(); // Log tree before expansion. Beagle_LogDebugM( ioContext.getSystem().getLogger(), "Tree before expansion" ); Beagle_LogDebugM( ioContext.getSystem().getLogger(), ioTree ); // Get the module index and reference. Module::Handle lModuleInstance = castHandleT<Module>(ioTree[inNodeToExpand].mPrimitive); unsigned int lModuleIndex = lModuleInstance->getIndex(); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Expanding ")+uint2ordinal(lModuleIndex+1)+ std::string(" module (called from ")+uint2ordinal(inNodeToExpand+1)+ std::string(" node of the tree)") ); ModuleVectorComponent::Handle lModuleVectorComponent = castHandleT<ModuleVectorComponent>(ioContext.getSystem().getComponent("ModuleVector")); if(lModuleVectorComponent==NULL) { throw Beagle_RunTimeExceptionM(std::string("GP system is not configured with a module vector. ")+ std::string("Consider adding a GP::ModuleVectorComponent object to the system.")); } Beagle::GP::Tree::Handle lModule = (*lModuleVectorComponent)[lModuleIndex]; Beagle_LogDebugM( ioContext.getSystem().getLogger(), *lModule ); // Generate new tree. const Factory& lFactory = ioContext.getSystem().getFactory(); GP::Tree::Alloc::Handle lTreeAlloc = castHandleT<GP::Tree::Alloc>(lFactory.getConceptAllocator("Genotype")); GP::Tree::Handle lNewTree = castHandleT<GP::Tree>(lTreeAlloc->allocate()); std::string lArgName = lModuleInstance->getArgsName(); ioTree.setContextToNode(inNodeToExpand, ioContext); for(unsigned int i=0; i<lModule->size(); ++i) { if((*lModule)[i].mPrimitive->getName() != lArgName) { lNewTree->push_back(GP::Node((*lModule)[i].mPrimitive)); } else { GP::Argument::Handle lArg = castHandleT<GP::Argument>((*lModule)[i].mPrimitive); const unsigned int lChildIndex = ioTree[inNodeToExpand].mPrimitive->getChildrenNodeIndex(lArg->getIndex(), ioContext); lNewTree->insert(lNewTree->end(), ioTree.begin()+lChildIndex, ioTree.begin()+lChildIndex+ioTree[lChildIndex].mSubTreeSize); } } ioTree.erase(ioTree.begin()+inNodeToExpand, ioTree.begin()+inNodeToExpand+ioTree[inNodeToExpand].mSubTreeSize); ioTree.insert(ioTree.begin()+inNodeToExpand, lNewTree->begin(), lNewTree->end()); ioTree.fixSubTreeSize(); // Log results. Beagle_LogDebugM( ioContext.getSystem().getLogger(), "Tree after expansion" ); Beagle_LogDebugM( ioContext.getSystem().getLogger(), ioTree ); Beagle_StackTraceEndM(); }