/*! * \brief Push execution context to prepare the execution of the argument. * \param inNumberArguments Number of arguments of called tree. * \param ioContext Evolutionary context. */ void GP::Argument::pushExecutionContext(unsigned int inNumberArguments, GP::Context& ioContext) { Beagle_StackTraceBeginM(); switch(mSharedData->mEvalMode) { case eCaching: { Object::Bag::Handle lNewCache = new Object::Bag(inNumberArguments, NULL); mSharedData->mCaches.push_back(lNewCache); Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(ioContext.getSystem().getFactory().getConceptAllocator("Context")); GP::Context::Handle lNewEvalContext = castHandleT<GP::Context>(lContextAlloc->clone(ioContext)); mSharedData->mEvalContext.push_back(lNewEvalContext); break; } case eJustInTime: { Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(ioContext.getSystem().getFactory().getConceptAllocator("Context")); GP::Context::Handle lNewEvalContext = castHandleT<GP::Context>(lContextAlloc->clone(ioContext)); mSharedData->mEvalContext.push_back(lNewEvalContext); break; } case ePreCompute: { Object::Bag::Handle lNewCache = new Object::Bag(inNumberArguments, NULL); lNewCache->resize(inNumberArguments); for(unsigned int i=0; i<inNumberArguments; ++i) { Object::Handle lArgI = mSharedData->mTypeAllocator->allocate(); getArgument(i, *lArgI, ioContext); (*lNewCache)[i] = lArgI; } mSharedData->mCaches.push_back(lNewCache); } default: { throw Beagle_InternalExceptionM(std::string("Undefined evaluation mode (")+ uint2str(mSharedData->mEvalMode)+std::string(") for the arguments!")); } } Beagle_StackTraceEndM(); }
/*! * \brief Apply the crossover operation on a breeding pool, returning a mated individual. * \param inBreedingPool Breeding pool to use for the crossover operation. * \param inChild Node handle associated to child node in the breeder tree. * \param ioContext Evolutionary context of the crossover operation. * \return Mated individual. */ Individual::Handle CrossoverOp::breed(Individual::Bag& inBreedingPool, BreederNode::Handle inChild, Context& ioContext) { Beagle_StackTraceBeginM(); Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(ioContext.getSystem().getFactory().getConceptAllocator("Context")); Context::Handle lContext2 = castHandleT<Context>(lContextAlloc->clone(ioContext)); Beagle_NonNullPointerAssertM(inChild); Beagle_NonNullPointerAssertM(inChild->getBreederOp()); Individual::Handle lIndiv1 = inChild->getBreederOp()->breed(inBreedingPool, inChild->getFirstChild(), ioContext); Beagle_NonNullPointerAssertM(inChild->getNextSibling()); Beagle_NonNullPointerAssertM(inChild->getNextSibling()->getBreederOp()); Individual::Handle lIndiv2 = inChild->getNextSibling()->getBreederOp()->breed(inBreedingPool, inChild->getNextSibling()->getFirstChild(), *lContext2); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Mating the ")+uint2ordinal(ioContext.getIndividualIndex()+1)+ std::string(" individual with the ")+uint2ordinal(lContext2->getIndividualIndex()+1)+ " individual" ); if((lIndiv1 != NULL) && (lIndiv2 != NULL)) { bool lMated = mate(*lIndiv1, ioContext, *lIndiv2, *lContext2); if(lMated) { if(lIndiv1->getFitness() != NULL) lIndiv1->getFitness()->setInvalid(); if(lIndiv2->getFitness() != NULL) lIndiv2->getFitness()->setInvalid(); History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); if(lHistory != NULL) { std::vector<HistoryID> lParents; HistoryID::Handle lHID1 = castHandleT<HistoryID>(lIndiv1->getMember("HistoryID")); if(lHID1 != NULL) lParents.push_back(*lHID1); HistoryID::Handle lHID2 = castHandleT<HistoryID>(lIndiv2->getMember("HistoryID")); if(lHID2 != NULL) lParents.push_back(*lHID2); lHistory->incrementHistoryVar(*lIndiv1); lHistory->trace(ioContext, lParents, lIndiv1, getName(), "crossover"); } } } return lIndiv1; Beagle_StackTraceEndM(); }
/*! * \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. * * This method evaluates only a single individual. For this * operator, it is much better to group individuals into a bag and * pass the bag to evaluate(Individual::Bag& ioIndividuals, Context::Bag& ioContexts). */ Fitness::Handle EvaluationMultipleOp::evaluate(Individual& inIndividual, Context& ioContext) { Beagle_StackTraceBeginM(); // Create a bag for the individual Individual::Bag lIndividuals; lIndividuals.resize(1); Beagle_AssertM(inIndividual == ioContext.getIndividual()); lIndividuals[0] = ioContext.getIndividualHandle(); // Create a context for the individual Context::Bag lContexts; lContexts.resize(1); Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(ioContext.getSystem().getFactory().getConceptAllocator("Context")); lContexts[0] = castHandleT<Context>(lContextAlloc->clone(ioContext)); // Call evalutate() Fitness::Bag::Handle lFitnessBag = evaluateIndividuals(lIndividuals,lContexts); // Return fitness Beagle_AssertM( !lFitnessBag->empty() ); return lFitnessBag->at(0); Beagle_StackTraceEndM(); }
/*! * \brief Add individuals to the bag such that the total equals getIndisPerGroup(). * \param ioIndividuals Bag of individuals to evaluate. * \param ioContexts Bag of evolutionary context. * \return The number of individuals added to the bag. * * The new individuals are chosen from the current deme. */ unsigned int EvaluationMultipleOp::enlargeGroup(Individual::Bag& ioIndividuals, Context::Bag& ioContexts) { Beagle_StackTraceBeginM(); Context& lContext = castObjectT<Context&>(*(ioContexts[0])); // Calculate the number of individuals to add unsigned int lNumToAdd = mIndisPerGroup - ioIndividuals.size(); Beagle_LogVerboseM( lContext.getSystem().getLogger(), std::string("Adding ")+uint2str(lNumToAdd)+std::string(" individuals to the group (for padding)") ); // Resize the bags unsigned int lIndisCounter = ioIndividuals.size(); ioIndividuals.resize(mIndisPerGroup); ioContexts.resize(mIndisPerGroup); // Loop through all the individuals in the deme Deme& lDeme = lContext.getDeme(); std::vector<unsigned int> lSelectableIndis; lSelectableIndis.resize(lDeme.size()); unsigned int lSelectableIndisCounter = 0; for (unsigned int i=0; i<lDeme.size(); i++) { // Loop through all the individuals in the bag bool lAdd = true; for(unsigned int j=0; j<ioIndividuals.size(); j++) { if(lDeme[i] == ioIndividuals[j]) { lAdd = false; break; } } // If the individual is not already in the bag, add it as an option if(lAdd) { lSelectableIndis[lSelectableIndisCounter] = i; lSelectableIndisCounter++; } } // Check there are sufficient individuals to choose if(lSelectableIndis.size() < lNumToAdd) { throw Beagle_RunTimeExceptionM("There are insufficient individuals in the deme to perform evaluation"); } // Add individuals for(unsigned int i=0; i<lNumToAdd; i++) { unsigned int lIndex = lContext.getSystem().getRandomizer().rollInteger(0,lSelectableIndisCounter-1); unsigned int lIndiIndex = lSelectableIndis[lIndex]; Beagle_LogVerboseM( lContext.getSystem().getLogger(), std::string("Adding ")+uint2ordinal(lIndiIndex+1)+ std::string(" individual to the group (for padding)") ); Beagle_AssertM(lIndiIndex < lDeme.size()); ioIndividuals[lIndisCounter] = lDeme[ lIndiIndex ]; Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(lContext.getSystem().getFactory().getConceptAllocator("Context")); ioContexts[lIndisCounter] = castHandleT<Context>(lContextAlloc->clone(*(ioContexts[0]))); ioContexts[lIndisCounter]->setIndividualHandle( ioIndividuals[lIndisCounter] ); ioContexts[lIndisCounter]->setIndividualIndex( lIndiIndex ); lIndisCounter++; } Beagle_AssertM( lIndisCounter==ioIndividuals.size() ); return lNumToAdd; Beagle_StackTraceEndM(); }
/*! * \brief Apply the evaluation process on the invalid individuals of the deme. * \param ioDeme Deme to process. * \param ioContext Context of the evolution. */ void EvaluationMultipleOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_LogTraceM( ioContext.getSystem().getLogger(), "Evaluating the fitness of the individuals in the " << uint2ordinal(ioContext.getDemeIndex()+1) << " deme" ); Beagle_AssertM( ioDeme.size()!=0 ); // Prepare stats prepareStats(ioDeme,ioContext); // Generate a vector of indicies into the population std::vector<unsigned int> lEvalVector; for(unsigned int i=0; i<ioDeme.size(); i++) { if((ioDeme[i]->getFitness() == NULL) || (ioDeme[i]->getFitness()->isValid() == false)) { lEvalVector.push_back(i); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "Added " << uint2ordinal(i+1) << " individual for evaluation." ); } } std::random_shuffle(lEvalVector.begin(), lEvalVector.end(), ioContext.getSystem().getRandomizer()); Beagle_LogDebugM( ioContext.getSystem().getLogger(), "There are " << lEvalVector.size() << " individuals to be evaluated." ); History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); while ( !lEvalVector.empty() ) { // Put individuals and context into bags. Individual::Bag lIndividuals; Context::Bag lContexts; lIndividuals.resize( mIndisPerGroup ); lContexts.resize( mIndisPerGroup ); unsigned int lIndiCounter =0; for (unsigned int i=0; i<mIndisPerGroup; i++) { // Set individual lIndividuals[i] = ioDeme[lEvalVector.back()]; lIndiCounter++; // Set context Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(ioContext.getSystem().getFactory().getConceptAllocator("Context")); Context::Handle lContext = castHandleT<Context>(lContextAlloc->clone(ioContext)); lContext->setIndividualIndex( lEvalVector.back() ); lContext->setIndividualHandle( ioDeme[lEvalVector.back()] ); lContexts[i] = lContext; // Remove this index from the evaluation vector lEvalVector.pop_back(); if(lEvalVector.empty()) { lIndividuals.resize( lIndiCounter ); lContexts.resize( lIndiCounter ); break; } } // Evaluate individuals std::ostringstream lOSS; lOSS << "Evaluating the fitness of the "; for(unsigned int i=0; i<lIndiCounter; i++) { // Add to message if (i==lIndiCounter-1) lOSS << " and "; lOSS << uint2ordinal(lContexts[i]->getIndividualIndex()+1); if (i<lIndiCounter-2) lOSS << ", "; } lOSS << " individuals"; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), lOSS.str() ); Fitness::Bag::Handle lFitnessBag = evaluateIndividuals(lIndividuals, lContexts); // Assign fitnesses for (unsigned int i=0; i<lIndiCounter; i++) { Beagle_LogDebugM( ioContext.getSystem().getLogger(), "Considering fitness of the " << uint2ordinal(lContexts[i]->getIndividualIndex()+1) << " individual" ); Beagle_AssertM( i < lFitnessBag->size() ); Fitness::Handle lFitness = lFitnessBag->at(i); Beagle_NonNullPointerAssertM( lFitness ); lIndividuals[i]->setFitness( lFitness ); lIndividuals[i]->getFitness()->setValid(); if(lHistory != NULL) { lHistory->allocateID(*lIndividuals[i]); lHistory->trace(ioContext, std::vector<HistoryID>(), lIndividuals[i], getName(), "evaluation"); } Beagle_LogVerboseM( ioContext.getSystem().getLogger(), *lIndividuals[i]->getFitness() ); } // Update stats updateStats(lIndividuals.size(),ioContext); } updateHallOfFameWithDeme(ioDeme,ioContext); Beagle_StackTraceEndM(); }
/*! * \brief Swap subtree mutate a GP individual. * \param ioIndividual GP individual to swap subtree mutate. * \param ioContext Context of the evolution. */ bool GP::MutationSwapSubtreeOp::mutate(Beagle::Individual& ioIndividual, Beagle::Context& ioContext) { Beagle_StackTraceBeginM(); // Initial parameters checks. Beagle_AssertM(ioIndividual.size() > 0); Beagle_ValidateParameterM(mNumberAttempts->getWrappedValue()>0, "gp.try", ">0"); // Cast method arguments. GP::Individual& lGPIndiv = castObjectT<GP::Individual&>(ioIndividual); GP::Context& lContext1 = castObjectT<GP::Context&>(ioContext); Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(ioContext.getSystem().getFactory().getConceptAllocator("Context")); GP::Context::Handle lContextHdl2 = castHandleT<GP::Context>(lContextAlloc->clone(lContext1)); const Factory& lFactory = ioContext.getSystem().getFactory(); GP::Tree::Alloc::Handle lTreeAlloc = castHandleT<GP::Tree::Alloc>(lFactory.getConceptAllocator("Genotype")); // Get parameters in local values, with the total number of nodes of the mutated individual. bool lMatingDone = false; float lDistrProba = mDistributionProba->getWrappedValue(); unsigned int lMaxTreeDepth = mMaxTreeDepth->getWrappedValue(); GP::Tree::Handle lOldTreeHandle1 = lContext1.getGenotypeHandle(); unsigned int lOldTreeIndex1 = lContext1.getGenotypeIndex(); unsigned int lSizeIndiv = 0; for(unsigned int i=0; i<lGPIndiv.size(); ++i) lSizeIndiv += lGPIndiv[i]->size(); // Some outputs. Beagle_LogDebugM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", "Individual tried for swap subtree mutation (before)" ); Beagle_LogObjectDebugM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", lGPIndiv ); // Mutation loop. Try the given number of attempts to mutation the individual. for(unsigned int lAttempt=0; lAttempt < mNumberAttempts->getWrappedValue(); lAttempt++) { // Calculate the number of nodes in the individual unsigned int lNbNodes = 0; for(unsigned int i=0; i<lGPIndiv.size(); i++) lNbNodes += lGPIndiv[i]->size(); if(lNbNodes == 0) return false; // Choose a node of the individual to mutate. unsigned int lNode1 = lContext1.getSystem().getRandomizer().rollInteger(0, lNbNodes-1); // Get the tree in which the choosen node is. Change the global node index to the tree's index. unsigned int lChoosenTree = 0; for(; lChoosenTree<lGPIndiv.size(); ++lChoosenTree) { if(lNode1 < lGPIndiv[lChoosenTree]->size()) break; Beagle_AssertM(lNode1 >= lGPIndiv[lChoosenTree]->size()); lNode1 -= lGPIndiv[lChoosenTree]->size(); } Beagle_AssertM(lChoosenTree < lGPIndiv.size()); // Cannot do anything with an tree of size <= 1. if(lGPIndiv[lChoosenTree]->size() <= 1) continue; // Some outputs. Beagle_LogVerboseM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", std::string("Trying a swap subtree mutation of the ")+uint2ordinal(lChoosenTree+1)+ std::string(" tree") ); // Make two clones of the choosen tree. GP::Tree::Handle lTreeClone1 = castHandleT<GP::Tree>(lTreeAlloc->clone(*lGPIndiv[lChoosenTree])); GP::Tree::Handle lTreeClone2 = castHandleT<GP::Tree>(lTreeAlloc->clone(*lGPIndiv[lChoosenTree])); // Now we decide whether the swap subtree mutation is internal or external. bool lMutationType = lContext1.getSystem().getRandomizer().rollUniform(0.0, 1.0) < lDistrProba; // Cannot do an internal mutation when there is only one branch in the tree. if(lTreeClone1->size() == (*lTreeClone1)[0].mPrimitive->getNumberArguments()+1) lMutationType = false; // This is special case, a linear tree. Cannot do an external mutation. if(lTreeClone1->size() == (*lTreeClone1)[1].mSubTreeSize+1) { if(lTreeClone1->size()==2) continue; // Cannot do anything here with the tree. lMutationType = true; } // lMutationType is true -> internal mutation if(lMutationType) { // If the selected node is a terminal, or a branch with a subtree made only of terminals, // choose another node in the same tree. while((*lTreeClone1)[lNode1].mSubTreeSize == ((*lTreeClone1)[lNode1].mPrimitive->getNumberArguments()+1)) { lNode1 = lContext1.getSystem().getRandomizer().rollInteger(0, lTreeClone1->size()-1); } // Choosing the second node, a branch in lNode1's subtree. unsigned int lSubTreeSizeN1 = (*lTreeClone1)[lNode1].mSubTreeSize; unsigned int lN2OffN1 = lContext1.getSystem().getRandomizer().rollInteger(1, lSubTreeSizeN1-1); unsigned int lNode2 = lNode1 + lN2OffN1; while((*lTreeClone1)[lNode2].mPrimitive->getNumberArguments() == 0) { lN2OffN1 = lContext1.getSystem().getRandomizer().rollInteger(1, lSubTreeSizeN1-1); lNode2 = lNode1 + lN2OffN1; } // Choosing the third node, any node in lNode2's subtree. unsigned int lSubTreeSizeN2 = (*lTreeClone1)[lNode2].mSubTreeSize; unsigned int lN3OffN2 = lContext1.getSystem().getRandomizer().rollInteger(1, lSubTreeSizeN2-1); // Ok, now we can exchange the subtrees. // New value of lNode1 and lNode2 for the second exchange. unsigned int lNode3Exch2 = lNode1 + lN3OffN2; unsigned int lNode1Exch2 = lNode2; // New value of lNode1 and lNode2 for the third exchange. unsigned int lNode2Exch3 = lNode1 + lN3OffN2 + lN2OffN1; unsigned int lNode3Exch3 = lNode2; // First exchange. lTreeClone1->setContextToNode(lNode1, lContext1); lTreeClone2->setContextToNode(lNode2, *lContextHdl2); exchangeSubTrees(*lTreeClone1, lNode1, lContext1, *lTreeClone2, lNode2, *lContextHdl2); // Second exchange. lTreeClone1->setContextToNode(lNode3Exch2, lContext1); lTreeClone2->setContextToNode(lNode1Exch2, *lContextHdl2); exchangeSubTrees(*lTreeClone1, lNode3Exch2, lContext1, *lTreeClone2, lNode1Exch2, *lContextHdl2); // Third exchange. lTreeClone1->setContextToNode(lNode2Exch3, lContext1); lTreeClone2->setContextToNode(lNode3Exch3, *lContextHdl2); exchangeSubTrees(*lTreeClone1, lNode2Exch3, lContext1, *lTreeClone2, lNode3Exch3, *lContextHdl2); // Checking if the tree depth is respected. If not, start again. if(lTreeClone1->getTreeDepth() > lMaxTreeDepth) { Beagle_LogVerboseM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", "Tree maximum depth exceeded. GP swap subtree mutation invalid." ); continue; } lGPIndiv[lChoosenTree] = lTreeClone1; Beagle_LogVerboseM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", "GP swap subtree mutation valid" ); lMatingDone = true; break; // The swap subtree mutation is valid. } // lMutationType is false -> external mutation else { // Deterniming the minimal node index to use. unsigned int lMinNodeIndex = 0; for(; lTreeClone1->size() == ((*lTreeClone1)[lMinNodeIndex].mSubTreeSize+lMinNodeIndex); ++lMinNodeIndex) { if(lMinNodeIndex == (lTreeClone1->size()-1)) continue; // Can't do anything with linear tree. } // Change lNode1 if less than minimum node index. if(lNode1 < lMinNodeIndex) lNode1 = lContext1.getSystem().getRandomizer().rollInteger(lMinNodeIndex, lTreeClone1->size()-1); // Choosing second swap subtree mutation point. std::vector<unsigned int> lValidN2; for(unsigned int i=lMinNodeIndex; i<lTreeClone1->size(); ++i) { if((i>=lNode1) && (i<lNode1+(*lTreeClone1)[lNode1].mSubTreeSize)) continue; else if((lNode1>=i) && (lNode1<(i+(*lTreeClone1)[i].mSubTreeSize))) continue; else lValidN2.push_back(i); } unsigned int lNode2 = lValidN2[lContext1.getSystem().getRandomizer().rollInteger(0, lValidN2.size()-1)]; Beagle_LogVerboseM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", std::string("Trying an external swap subtree mutation of the ")+uint2ordinal(lNode1+1)+ std::string(" node with the subtree to the ")+uint2ordinal(lNode2+1)+ std::string(" node") ); // Ok, now we can exchange the subtrees. // New value of lNode1 and lNode2 for the second exchange. unsigned int lNode1Exch2 = lNode1; unsigned int lNode2Exch2 = lNode2; if(lNode1 < lNode2) { lNode2Exch2 += (*lTreeClone1)[lNode2].mSubTreeSize; lNode2Exch2 -= (*lTreeClone1)[lNode1].mSubTreeSize; } else { lNode1Exch2 += (*lTreeClone1)[lNode1].mSubTreeSize; lNode1Exch2 -= (*lTreeClone1)[lNode2].mSubTreeSize; } // First exchange. lTreeClone1->setContextToNode(lNode1, lContext1); lTreeClone2->setContextToNode(lNode2, *lContextHdl2); exchangeSubTrees(*lTreeClone1, lNode1, lContext1, *lTreeClone2, lNode2, *lContextHdl2); // Second exchange. lTreeClone1->setContextToNode(lNode2Exch2, lContext1); lTreeClone2->setContextToNode(lNode1Exch2, *lContextHdl2); exchangeSubTrees(*lTreeClone1, lNode2Exch2, lContext1, *lTreeClone2, lNode1Exch2, *lContextHdl2); // Checking if the tree depth is respected. If not, start again. if(lTreeClone1->getTreeDepth() > lMaxTreeDepth) { Beagle_LogVerboseM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", "Tree maximum depth exceeded. GP swap subtree mutation invalid." ); continue; } lGPIndiv[lChoosenTree] = lTreeClone1; Beagle_LogVerboseM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", "GP swap subtree mutation valid" ); lMatingDone = true; break; // The swap subtree mutation is valid. } } // Replace the contexts. lContext1.setGenotypeHandle(lOldTreeHandle1); lContext1.setGenotypeIndex(lOldTreeIndex1); if(lMatingDone) { Beagle_LogDebugM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", "Individual after swap subtree mutation" ); Beagle_LogObjectDebugM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", lGPIndiv ); } else { Beagle_LogVerboseM( lContext1.getSystem().getLogger(), "mutation", "Beagle::GP::MutationSwapSubtreeOp", "No GP swap subtree mutation done" ); } return lMatingDone; Beagle_StackTraceEndM(); }
/*! * \brief Apply the crossover operation on the deme. * \param ioDeme Current deme of individuals to mate. * \param ioContext Context of the evolution. */ void CrossoverOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_ValidateParameterM(mMatingProba->getWrappedValue()>=0.0, mMatingProbaName, "<0"); Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("Mating individuals of the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Mating individuals with probability ")+ dbl2str(mMatingProba->getWrappedValue()) ); History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); Individual::Handle lOldIndividualHandle = ioContext.getIndividualHandle(); unsigned int lOldIndividualIndex = ioContext.getIndividualIndex(); std::vector<unsigned int> lMateVector; for(unsigned int i=0; i<ioDeme.size(); i++) { if(ioContext.getSystem().getRandomizer().rollUniform() <= mMatingProba->getWrappedValue()) { lMateVector.push_back(i); } } std::random_shuffle(lMateVector.begin(), lMateVector.end(), ioContext.getSystem().getRandomizer()); if((lMateVector.size() % 2) != 0) lMateVector.pop_back(); int j = 0; int lSize = lMateVector.size(); #if defined(BEAGLE_USE_OMP_NR) || defined(BEAGLE_USE_OMP_R) static OpenMP::Handle lOpenMP = castHandleT<OpenMP>(ioContext.getSystem().getComponent("OpenMP")); const Factory& lFactory = ioContext.getSystem().getFactory(); const std::string& lContextName = lFactory.getConceptTypeName("Context"); Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(lFactory.getAllocator(lContextName)); Context::Bag lContexts(lOpenMP->getMaxNumThreads()); Context::Bag lContexts2(lOpenMP->getMaxNumThreads()); for(unsigned int i = 0; i < lOpenMP->getMaxNumThreads(); ++i) { lContexts[i] = castHandleT<Context>(lContextAlloc->clone(ioContext)); lContexts2[i] = castHandleT<Context>(lContextAlloc->clone(ioContext)); } #if defined(BEAGLE_USE_OMP_NR) #pragma omp parallel for shared(lSize, lMateVector, lHistory, lContexts, lContexts2) private(j) schedule(dynamic) #elif defined(BEAGLE_USE_OMP_R) const int lChunkSize = std::max((int)(lSize / lOpenMP->getMaxNumThreads()), 1); #pragma omp parallel for shared(lSize, lMateVector, lHistory, lContexts, lContexts2) private(j) schedule(static, lChunkSize) #endif #else Context::Alloc::Handle lContextAlloc = castHandleT<Context::Alloc>(ioContext.getSystem().getFactory().getConceptAllocator("Context")); Context::Handle lContext2 = castHandleT<Context>(lContextAlloc->clone(ioContext)); #endif for(j=0; j<lSize; j+=2) { unsigned int lFirstMate = lMateVector[j]; unsigned int lSecondMate = lMateVector[j+1]; #if defined(BEAGLE_USE_OMP_NR) || defined(BEAGLE_USE_OMP_R) lContexts[lOpenMP->getThreadNum()]->setIndividualIndex(lFirstMate); lContexts[lOpenMP->getThreadNum()]->setIndividualHandle(ioDeme[lFirstMate]); lContexts2[lOpenMP->getThreadNum()]->setIndividualIndex(lSecondMate); lContexts2[lOpenMP->getThreadNum()]->setIndividualHandle(ioDeme[lSecondMate]); #else ioContext.setIndividualIndex(lFirstMate); ioContext.setIndividualHandle(ioDeme[lFirstMate]); lContext2->setIndividualIndex(lSecondMate); lContext2->setIndividualHandle(ioDeme[lSecondMate]); #endif Beagle_LogVerboseM( ioContext.getSystem().getLogger(), std::string("Mating the ")+uint2ordinal(lFirstMate+1)+ std::string(" individual with the ")+uint2ordinal(lSecondMate+1)+" individual" ); std::vector<HistoryID> lParents; if(lHistory != NULL) { #pragma omp critical (Beagle_History) { HistoryID::Handle lHID1 = castHandleT<HistoryID>(ioDeme[lFirstMate]->getMember("HistoryID")); if(lHID1 != NULL) lParents.push_back(*lHID1); HistoryID::Handle lHID2 = castHandleT<HistoryID>(ioDeme[lSecondMate]->getMember("HistoryID")); if(lHID2 != NULL) lParents.push_back(*lHID2); } } #if defined(BEAGLE_USE_OMP_NR) || defined(BEAGLE_USE_OMP_R) bool lMated = mate(*ioDeme[lFirstMate], *(lContexts[lOpenMP->getThreadNum()]), *ioDeme[lSecondMate], *(lContexts2[lOpenMP->getThreadNum()])); #else bool lMated = mate(*ioDeme[lFirstMate], ioContext, *ioDeme[lSecondMate], *lContext2); #endif if(lMated) { if(ioDeme[lFirstMate]->getFitness() != NULL) { ioDeme[lFirstMate]->getFitness()->setInvalid(); } if(ioDeme[lSecondMate]->getFitness() != NULL) { ioDeme[lSecondMate]->getFitness()->setInvalid(); } if(lHistory != NULL) { #pragma omp critical (Beagle_History) { lHistory->incrementHistoryVar(*ioDeme[lFirstMate]); #if defined(BEAGLE_USE_OMP_R) || defined(BEAGLE_USE_OMP_NR) lHistory->trace(*lContexts[lOpenMP->getThreadNum()], lParents, ioDeme[lFirstMate], getName(), "crossover"); #else lHistory->trace(ioContext, lParents, ioDeme[lFirstMate], getName(), "crossover"); #endif lHistory->incrementHistoryVar(*ioDeme[lSecondMate]); #if defined(BEAGLE_USE_OMP_R) || defined(BEAGLE_USE_OMP_NR) lHistory->trace(*lContexts[lOpenMP->getThreadNum()], lParents, ioDeme[lSecondMate], getName(), "crossover"); #else lHistory->trace(ioContext, lParents, ioDeme[lSecondMate], getName(), "crossover"); #endif } } } } ioContext.setIndividualIndex(lOldIndividualIndex); ioContext.setIndividualHandle(lOldIndividualHandle); Beagle_StackTraceEndM(); }