/*! * \brief Apply the operation on a deme in the given context. * \param ioDeme Reference to the deme on which the operation takes place. * \param ioContext Evolutionary context of the operation. */ void GenerationalOp::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); Beagle_NonNullPointerAssertM(getRootNode()); Beagle_NonNullPointerAssertM(mElitismKeepSize); Beagle_ValidateParameterM(mElitismKeepSize->getWrappedValue() <= ioDeme.size(), "ec.elite.keepsize", "The elistism keepsize must be less than the deme size!"); Beagle_LogTraceM( ioContext.getSystem().getLogger(), "Processing using generational replacement strategy the " << uint2ordinal(ioContext.getDemeIndex()+1) << " deme" ); Beagle_LogTraceM(ioContext.getSystem().getLogger(), (*this)); RouletteT<unsigned int> lRoulette; buildRoulette(lRoulette, ioContext); Individual::Bag lOffsprings; const Factory& lFactory = ioContext.getSystem().getFactory(); if(mElitismKeepSize->getWrappedValue() > 0) { History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History")); std::make_heap(ioDeme.begin(), ioDeme.end(), IsLessPointerPredicate()); for(unsigned int i=0; i<mElitismKeepSize->getWrappedValue(); ++i) { std::string lIndividualType = ioDeme[0]->getType(); Individual::Alloc::Handle lIndividualAlloc = castHandleT<Individual::Alloc>(lFactory.getAllocator(lIndividualType)); Individual::Handle lEliteIndiv = castHandleT<Individual>(lIndividualAlloc->allocate()); lEliteIndiv->copy(*ioDeme[0], ioContext.getSystem()); lOffsprings.push_back(lEliteIndiv); if(lHistory != NULL) { HistoryID::Handle lHID = castHandleT<HistoryID>(ioDeme[0]->getMember("HistoryID")); std::vector<HistoryID> lParent; if(lHID != NULL) lParent.push_back(*lHID); lHistory->allocateNewID(*lEliteIndiv); lHistory->trace(ioContext, lParent, lEliteIndiv, getName(), "elitism"); } std::pop_heap(ioDeme.begin(), (ioDeme.end()-i), IsLessPointerPredicate()); } } for(unsigned int i=mElitismKeepSize->getWrappedValue(); i<ioDeme.size(); ++i) { unsigned int lIndexBreeder = lRoulette.select(ioContext.getSystem().getRandomizer()); BreederNode::Handle lSelectedBreeder=getRootNode(); for(unsigned int j=0; j<lIndexBreeder; ++j) lSelectedBreeder=lSelectedBreeder->getNextSibling(); Beagle_NonNullPointerAssertM(lSelectedBreeder); Beagle_NonNullPointerAssertM(lSelectedBreeder->getBreederOp()); Individual::Handle lBredIndiv = lSelectedBreeder->getBreederOp()->breed(ioDeme, lSelectedBreeder->getFirstChild(), ioContext); Beagle_NonNullPointerAssertM(lBredIndiv); lOffsprings.push_back(lBredIndiv); } for(unsigned int j=0; j<lOffsprings.size(); ++j) ioDeme[j] = lOffsprings[j]; Beagle_StackTraceEndM(); }
/*! * \brief Apply NPGA2 multiobjective selection operator. * \param ioDeme Deme on which selection operator is applied. * \param ioContext Evolutionary context. */ void NPGA2Op::operate(Deme& ioDeme, Context& ioContext) { Beagle_StackTraceBeginM(); if(ioDeme.size() == 0) return; Beagle_LogTraceM( ioContext.getSystem().getLogger(), std::string("Applying NPGA2 multiobjective selection on the ")+ uint2ordinal(ioContext.getDemeIndex()+1)+" deme" ); std::vector<bool> lAlreadySelectedIndiv(ioDeme.size(), false); Individual::Bag lSelectedIndividual; const Factory& lFactory = ioContext.getSystem().getFactory(); // Generate new generation by selection for(unsigned int i=0; i<ioDeme.size(); ++i) { // First participant unsigned int lFirstParticipant = ioContext.getSystem().getRandomizer().rollInteger(0, ioDeme.size()-1); std::vector<unsigned int> lNDParticipants(1, lFirstParticipant); // Following participants to tournament for(unsigned int j=1; j<mNumberParticipants->getWrappedValue(); ++j) { unsigned int lParticipant = ioContext.getSystem().getRandomizer().rollInteger(0, ioDeme.size()-1); // Test if participant is dominated or dominate other participants bool lIsDominated = false; Fitness::Handle lPartFitness = ioDeme[lParticipant]->getFitness(); for(unsigned int k=0; k<lNDParticipants.size(); ++k) { Fitness::Handle lFitnessNDk = ioDeme[lNDParticipants[k]]->getFitness(); if(lPartFitness->isDominated(*lFitnessNDk)) { lIsDominated = true; } else if(lFitnessNDk->isDominated(*lPartFitness)) { lNDParticipants.erase(lNDParticipants.begin()+k); } } if(lIsDominated==false) lNDParticipants.push_back(lParticipant); } // Test if there is a tie. If so evaluate niche count. Beagle_AssertM(lNDParticipants.size() != 0); unsigned int lWinner = lNDParticipants[0]; if(lNDParticipants.size() > 1) { float lLowestNicheCount = evalNicheCount(*ioDeme[lNDParticipants[0]], lSelectedIndividual); for(unsigned int j=1; j<lNDParticipants.size(); ++j) { float lNicheCount = evalNicheCount(*ioDeme[lNDParticipants[j]], lSelectedIndividual); if(lNicheCount < lLowestNicheCount) { lLowestNicheCount = lNicheCount; lWinner = lNDParticipants[j]; } } } // Put winner in selected individual bag if(lAlreadySelectedIndiv[lWinner]) { std::string lIndividualType = ioDeme[lWinner]->getType(); Individual::Alloc::Handle lIndividualAlloc = castHandleT<Individual::Alloc>(lFactory.getAllocator(lIndividualType)); Individual::Handle lIndividual = castHandleT<Individual>(lIndividualAlloc->allocate()); lIndividual->copy(*ioDeme[lWinner], ioContext.getSystem()); lSelectedIndividual.push_back(lIndividual); Beagle_LogVerboseM( ioContext.getSystem().getLogger(), uint2ordinal(lWinner+1)+" individual selected again in NPGA2 selection process" ); } else { lSelectedIndividual.push_back(ioDeme[lWinner]); lAlreadySelectedIndiv[lWinner] = true; Beagle_LogVerboseM( ioContext.getSystem().getLogger(), uint2ordinal(lWinner+1)+" individual selected in NPGA2 selection process" ); } } // Copy selected individuals into deme for(unsigned int j=0; j<ioDeme.size(); ++j) ioDeme[j] = lSelectedIndividual[j]; Beagle_StackTraceEndM(); }