/*! * \brief Swap mutate a constrained GP individual. * \param ioIndividual GP individual to swap mutate. * \param ioContext Context of the evolution. * \return True if the individual is effectively mutated, false if not. */ bool GP::MutationSwapDepthSelectiveConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext) { Beagle_StackTraceBeginM(); GP::Individual& lIndividual = castObjectT<GP::Individual&>(ioIndividual); GP::Context& lContext = castObjectT<GP::Context&>(ioContext); double lDistrProba = mDistributionProba->getWrappedValue(); unsigned int lNumberAttempts = mNumberAttempts->getWrappedValue(); bool lMutationDone = false; //Select node to mutate unsigned int lChoosenTree = 0; unsigned int lChoosenNode = 0; bool lDoParameterSearch = (lContext.getSystem().getRandomizer().rollUniform(0.0, 1.0) <= mMutParameterPb->getWrappedValue()); RouletteT< std::pair<unsigned int,unsigned int> > lRoulette; //Select primitive based on type for(unsigned int lTry = 0; lTry < 2; ++lTry) { //Do only twice std::vector<const std::type_info*> lDesiredTypes(1, ArgEph); DepthDependentSelectionOp::buildRoulette(lRoulette, lDesiredTypes, lIndividual, lContext,!lDoParameterSearch,lDoParameterSearch); if(lRoulette.size() == 0) { if(lDoParameterSearch) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", string("No EphemeralDouble node found.") ); } else { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", string("No non EphemeralDouble node found.") ); } lDoParameterSearch = !lDoParameterSearch; if(lTry >= 1) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", "Unable to GP standard mutate the individual" ); return false; } } else { std::pair<unsigned int,unsigned int> lSelectedNode = lRoulette.select(ioContext.getSystem().getRandomizer()); lChoosenTree = lSelectedNode.first; lChoosenNode = lSelectedNode.second; break; } } if(lDoParameterSearch) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", string("Mutation applied only on EphemeralDouble node.") ); } else { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", string("Mutation applied on node that are not EphemeralDouble.") ); } GP::Tree& lTree = *lIndividual[lChoosenTree]; if(lTree.size() == 0) return false; GP::Tree::Handle lOldTreeHandle = lContext.getGenotypeHandle(); unsigned int lOldTreeIndex = lContext.getGenotypeIndex(); lContext.setGenotypeHandle(lIndividual[lChoosenTree]); lContext.setGenotypeIndex(lChoosenTree); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", std::string("Individual before constrained GP tree swap mutation: ")+ioIndividual.serialize() ); if(lTree.size() > 1) { bool lTypeNode = (lContext.getSystem().getRandomizer().rollUniform(0., 1.) < lDistrProba); //Clean the roulette to include only the choosen tree for(std::vector< std::pair<double, std::pair<unsigned int,unsigned int> > >::iterator lRouletteIter = lRoulette.begin(); lRouletteIter!=lRoulette.end();){ if(lRouletteIter->second.first != lChoosenTree || (lTree[lRouletteIter->second.second].mPrimitive->getNumberArguments() != 0) != lTypeNode ) { lRouletteIter = lRoulette.erase(lRouletteIter++); } else { ++lRouletteIter; } } if(lRoulette.size() > 0) lChoosenNode = lRoulette.select(ioContext.getSystem().getRandomizer()).second; } if( !lDoParameterSearch || lRoulette.size() > 0 ) { Primitive::Handle lOriginalPrimitive = lTree[lChoosenNode].mPrimitive; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", std::string("Trying to constrained GP tree swap mutate the ")+uint2ordinal(lChoosenNode+1)+ std::string(" node (primitive: \"")+lOriginalPrimitive->getName()+ std::string("\" nb args: ")+uint2str(lOriginalPrimitive->getNumberArguments())+ std::string(") of the ")+uint2ordinal(lChoosenTree+1)+std::string(" tree") ); GP::PrimitiveSet& lPrimitiveSet = lTree.getPrimitiveSet(lContext); unsigned int lNbArgsPrimit = lTree[lChoosenNode].mPrimitive->getNumberArguments(); lTree.setContextToNode(lChoosenNode, lContext); for(unsigned int lAttempt=0; lAttempt < lNumberAttempts; ++lAttempt) { Primitive::Handle lChoosenPrimitive = lPrimitiveSet.select(lNbArgsPrimit, lContext); if(lChoosenPrimitive==NULL) break; lTree[lChoosenNode].mPrimitive = lChoosenPrimitive->giveReference(lNbArgsPrimit, lContext); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", std::string("Trying the primitive \"")+lChoosenPrimitive->getName()+ std::string("\"") ); if(lTree.validateSubTree(lChoosenNode, lContext)) { lMutationDone = true; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", "Constrained GP tree swap mutation valid" ); break; } else { lTree[lChoosenNode].mPrimitive = lOriginalPrimitive; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", "Constrained GP tree swap mutation invalid" ); } } } lContext.setGenotypeHandle(lOldTreeHandle); lContext.setGenotypeIndex(lOldTreeIndex); if(lMutationDone) { if( !lDoParameterSearch ) { //Set structure id invalid castHandleT<TreeSTag>((lIndividual)[0])->setStructureIDInvalid(); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", std::string("Set structure id invalid") ); } Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", std::string("Individual after constrained GP swap mutation: ")+ ioIndividual.serialize() ); } else { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapDepthSelectiveConstrainedOp", "Unable to swap mutate the constrained individual" ); } return lMutationDone; Beagle_StackTraceEndM("bool GP::MutationSwapDepthSelectiveConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)"); }
/*! * \brief Standard mutate a constrained GP individual. * \param ioIndividual GP individual to standard mutate. * \param ioContext Context of the evolution. * \return True if the individual is effectively mutated, false if not. */ bool GP::MutationStandardSelectiveConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext) { Beagle_StackTraceBeginM(); GP::Individual& lIndividual = castObjectT<GP::Individual&>(ioIndividual); GP::Context& lContext = castObjectT<GP::Context&>(ioContext); unsigned int lMaxTreeDepth = mMaxTreeDepth->getWrappedValue(); unsigned int lMaxRegenerationDepth = mMaxRegenerationDepth->getWrappedValue(); //Select node to mutate unsigned int lChoosenTree = 0; unsigned int lChoosenNode = 0; bool lDoParameterSearch = (lContext.getSystem().getRandomizer().rollUniform(0.0, 1.0) <= mMutParameterPb->getWrappedValue()); //Select primitive based on type for(unsigned int lTry = 0; lTry < 2; ++lTry) { //Do only twice std::vector<const std::type_info*> lDesiredTypes(1, ArgEph); RouletteT< std::pair<unsigned int,unsigned int> > lRoulette; SelectiveConstrainedSelectionOp::buildRoulette(lRoulette, lDesiredTypes, lIndividual, lContext,!lDoParameterSearch,lDoParameterSearch); if(lRoulette.size() == 0) { if(lDoParameterSearch) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp", string("No EphemeralDouble node found.") ); } else { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp", string("No non EphemeralDouble node found.") ); } lDoParameterSearch = !lDoParameterSearch; if(lTry >= 1) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp", "Unable to GP standard mutate the individual" ); return false; } } else { std::pair<unsigned int,unsigned int> lSelectedNode = lRoulette.select(ioContext.getSystem().getRandomizer()); lChoosenTree = lSelectedNode.first; lChoosenNode = lSelectedNode.second; break; } } if(lDoParameterSearch) { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp", string("Mutation applied only on EphemeralDouble node.") ); } else { Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp", string("Mutation applied on node that are not EphemeralDouble.") ); } unsigned int lOldGenotypeIndex = lContext.getGenotypeIndex(); GP::Tree::Handle lOldGenotypeHandle = lContext.getGenotypeHandle(); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp", std::string("Individual before GP standard mutation: ")+ ioIndividual.serialize() ); GP::Tree::Handle lActualTree = lIndividual[lChoosenTree]; GP::Tree::Handle lNewTree = castHandleT<GP::Tree>(lIndividual.getTypeAlloc()->allocate()); lNewTree->setPrimitiveSetIndex(lActualTree->getPrimitiveSetIndex()); lNewTree->setNumberArguments(lActualTree->getNumberArguments()); unsigned int lChoosenNodeSubTreeSize = (*lActualTree)[lChoosenNode].mSubTreeSize; lNewTree->insert(lNewTree->end(), lActualTree->begin(), lActualTree->begin()+lChoosenNode); lContext.setGenotypeIndex(lChoosenTree); lContext.setGenotypeHandle(lActualTree); lContext.emptyCallStack(); lActualTree->setContextToNode(lChoosenNode, lContext); lContext.popCallStack(); const unsigned int lMaxSubTreeDepth = minOf<unsigned int>(lMaxTreeDepth - lContext.getCallStackSize(), lMaxRegenerationDepth); lIndividual[lChoosenTree] = lNewTree; lContext.setGenotypeHandle(lNewTree); unsigned int lAttempt=0; if(lMaxSubTreeDepth >= 1) { for(; lAttempt < mNumberAttempts->getWrappedValue(); lAttempt++) { if(mInitOp->initTree(*lNewTree, 1, lMaxSubTreeDepth, lContext) != 0) break; } } else { lAttempt = mNumberAttempts->getWrappedValue(); } if(lAttempt == mNumberAttempts->getWrappedValue()) { lIndividual[lChoosenTree] = lActualTree; lContext.setGenotypeIndex(lOldGenotypeIndex); lContext.setGenotypeHandle(lOldGenotypeHandle); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp", "Unable to GP standard mutate the individual" ); return false; } if( !lDoParameterSearch ) { //Set structure id invalid castHandleT<TreeSTag>((lIndividual)[0])->setStructureIDInvalid(); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp", std::string("Set structure id invalid") ); } Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp", std::string("GP standard mutate the ")+uint2ordinal(lChoosenNode+1)+ std::string(" node, ")+ (*lActualTree)[lChoosenNode].mPrimitive->getName() +std::string(", of the ")+uint2ordinal(lChoosenTree+1)+ std::string(" tree with max depth ")+uint2str(lMaxSubTreeDepth) ); lNewTree->insert(lNewTree->end(), lActualTree->begin()+lChoosenNode+lChoosenNodeSubTreeSize, lActualTree->end()); unsigned int lDiffSize = (*lActualTree)[lChoosenNode].mSubTreeSize - (*lNewTree)[lChoosenNode].mSubTreeSize; for(unsigned int l=0; l<lContext.getCallStackSize(); l++) { (*lNewTree)[lContext.getCallStackElement(l)].mSubTreeSize -= lDiffSize; } lContext.setGenotypeIndex(lOldGenotypeIndex); lContext.setGenotypeHandle(lOldGenotypeHandle); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "mutation", "Beagle::GP::MutationStandardSelectiveConstrainedOp", std::string("Individual after GP standard mutation: ")+ ioIndividual.serialize() ); return true; Beagle_StackTraceEndM("bool GP::MutationStandardSelectiveConstrainedOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext)"); }
/*! * \brief Evaluate the fitness of the given individual. * \param inIndividual Current individual to evaluate. * \param ioContext Evolutionary context. * \return Handle to the fitness value of the individual. */ Beagle::Fitness::Handle AnalogFilterParameterEvalOp::evaluate(Beagle::Individual& inIndividual, Beagle::Context& ioContext) { Beagle_AssertM(inIndividual.size() == 1); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), "evaluation", "AnalogFilterParameterEvalOp", std::string("Evaluating individual: ")+ inIndividual.serialize() ); BGFitness *lFitness = new BGFitness(0); GrowingBondGraph::Handle lBondGraph; GA::FloatVector::Handle lParametersVector = castHandleT<GA::FloatVector>(inIndividual[0]); BGContext& lBGContext = castObjectT<BGContext&>(ioContext); SpeciesGA& lSpecies = castObjectT<SpeciesGA&>(ioContext.getDeme()); RepresentantGP::Handle lIndividual = castHandleT<RepresentantGP>(lSpecies.getRepresentant()); TreeSTag::Handle lTree = castHandleT<TreeSTag>((*lIndividual)[0]); // lTree->assignNewParameterVector(lParametersVector, lBGContext); lBondGraph = lTree->getBondGraph(); lBondGraph->assignParameters(*lParametersVector); lIndividual->getFitness()->setInvalid(); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "evaluation", "AnalogFilterParameterEvalOp", std::string("Individual after parameter assignment: ")+ lIndividual->serialize() ); try { vector<double> lInitial; //Run the individual to create the bond graph. // RootReturn lResult; // // lBGContext.setIndividualHandle(lIndividual); // lIndividual->run(lResult, lBGContext); // lBondGraph = lBGContext.getBondGraph(); // lTree->setBondGraph(lBondGraph); // // //Set output bond // Bond* lOutputBond = lBondGraph->getComponents()[lResult.getValue()-1]->getPorts()[0]->getBond(); // lBondGraph->setOutputBonds(lOutputBond, 0); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "evaluation", "AnalogFilterParameterEvalOp", std::string("Evaluating bondgrap: ")+ lBondGraph->BondGraph::serialize() ); //lBondGraph->simplify(); //Get state equations lBondGraph->assignCausality(); lBondGraph->computeStateEquation(); PACC::Matrix lA,lB,lB2,lC,lD,lD2; lBondGraph->getStateMatrix(lA,lB,lB2); lBondGraph->getOutputMatrix(lC,lD,lD2); lFitness->addStateMatrix(lA); lFitness->addStateMatrix(lB); lFitness->addStateMatrix(lC); lFitness->addStateMatrix(lD); //Check to see if the system is LTI if(lBondGraph->hasDeferentialCausality()) { //lFitness->setValue(ioContext.getSystem().getRandomizer().getFloat()); lFitness->setValue(0); //delete lBondGraph; return lFitness; } else { #ifndef DEBUG_NOMATLAB //Evalute the response in Matlab. // Cast the state matrix as input data // The mwArray::SetData is copying in column major order and the PACC::Matrix is a row major order // Therefore, the matrix need to be transposed. PACC::Matrix lAt,lBt,lCt,lDt; if(!lA.empty()) lAt = lA.transpose(); if(!lB.empty()) lBt = lB.transpose(); if(!lC.empty()) lCt = lC.transpose(); if(!lD.empty()) lDt = lD.transpose(); double *lValueA = new double[lAt.size()]; std::copy(lAt.begin(), lAt.end(), lValueA); mwArray lArrayA(lAt.getCols(),lAt.getRows(), mxDOUBLE_CLASS, mxREAL); lArrayA.SetData(lValueA,lAt.size()); double *lValueB = new double[lBt.size()]; std::copy(lBt.begin(), lBt.end(), lValueB); mwArray lArrayB(lBt.getCols(),lBt.getRows(), mxDOUBLE_CLASS, mxREAL); lArrayB.SetData(lValueB,lBt.size()); double *lValueC = new double[lCt.size()]; std::copy(lCt.begin(), lCt.end(), lValueC); mwArray lArrayC(lCt.getCols(),lCt.getRows(), mxDOUBLE_CLASS, mxREAL); lArrayC.SetData(lValueC,lCt.size()); double *lValueD = new double[lDt.size()]; std::copy(lDt.begin(), lDt.end(), lValueD); mwArray lArrayD(lDt.getCols(),lDt.getRows(), mxDOUBLE_CLASS, mxREAL); lArrayD.SetData(lValueD,lDt.size()); // Create output array mwArray loutArray; // Call the library function AnalogFilterEval(1, loutArray, lArrayA, lArrayB, lArrayC,lArrayD); // Extract the output int lNbOutput = loutArray.NumberOfElements(); double* loutValues = new double[lNbOutput]; loutArray.GetData(loutValues, lNbOutput); // Bundle the fitness lFitness->setValue(loutValues[0]); delete [] lValueA; delete [] lValueB; delete [] lValueC; delete [] lValueD; delete [] loutValues; #else lFitness->setValue(ioContext.getSystem().getRandomizer().getFloat()); #endif } } catch (const mwException& inException) { std::cerr << inException.what() << std::endl; PACC::Matrix lA,lB,lB2,lC,lD,lD2; lBondGraph->getStateMatrix(lA,lB,lB2); lBondGraph->getOutputMatrix(lC,lD,lD2); PACC::XML::Streamer lStream(cerr); lA.write(lStream); cerr << endl; lB.write(lStream); cerr << endl; lC.write(lStream); cerr << endl; lD.write(lStream); cerr << endl; //Save bond graph for debuging std::ostringstream lFilename; lFilename << "bug/bondgraph_bug_" << ioContext.getGeneration() << "_" << ioContext.getIndividualIndex(); #ifndef WITHOUT_GRAPHVIZ lBondGraph->plotGraph(lFilename.str()+std::string(".svg")); #endif ofstream lFileStream((lFilename.str()+std::string(".xml")).c_str()); PACC::XML::Streamer lStreamer(lFileStream); lBondGraph->write(lStreamer); #ifdef STOP_ON_ERROR exit(EXIT_FAILURE); #endif } catch(std::runtime_error inError) { std::cerr << "Error catched while evaluating the bond graph: " << inError.what() << std::endl; //Save bond graph for debuging std::ostringstream lFilename; lFilename << "bug/bondgraph_bug_" << ioContext.getGeneration() << "_" << ioContext.getIndividualIndex(); #ifndef WITHOUT_GRAPHVIZ lBondGraph->plotGraph(lFilename.str()+std::string(".svg")); #endif ofstream lFileStream((lFilename.str()+std::string(".xml")).c_str()); PACC::XML::Streamer lStreamer(lFileStream); lBondGraph->write(lStreamer); //Assign null fitness lFitness->setValue(0); #ifdef XMLBEAGLE XMLStreamer lStreamer2(std::cout); inIndividual.write(lStreamer2); #else inIndividual.write(lStreamer); #endif #ifdef STOP_ON_ERROR exit(EXIT_FAILURE); #endif } //delete lBondGraph; return lFitness; }