Пример #1
0
/*!
 *  \brief Do fast non-dominated sort and evaluate Pareto fronts of data up to given size.
 *  \param outParetoFronts Pareto fronts from the fast ND sort.
 *  \param inSortStop Number of individuals on the Pareto fronts needed to stop the sort.
 *  \param inIndividualPool Pool of individuals to get next Pareto front of.
 *  \param ioContext Evolutionary context.
 */
void EMO::NSGA2Op::sortFastND(NSGA2Op::Fronts& outParetoFronts,
                         unsigned int inSortStop,
                         const Individual::Bag& inIndividualPool,
                         Context& ioContext) const
{
	Beagle_StackTraceBeginM();
	outParetoFronts.clear();
	if(inSortStop == 0) return;
	outParetoFronts.resize(1);
	unsigned int lParetoSorted = 0;
	// N: Number of dominating individuals
	std::vector<unsigned int> lN(inIndividualPool.size(), 0);
	// S: Set of dominated individuals
	Fronts lS(inIndividualPool.size());

	// First pass to get first Pareto front and domination sets
	for(unsigned int i=0; i<inIndividualPool.size(); ++i) {
		Fitness::Handle lFitI = inIndividualPool[i]->getFitness();
		for(unsigned int j=(i+1); j<inIndividualPool.size(); ++j) {
			Fitness::Handle lFitJ = inIndividualPool[j]->getFitness();
			if(lFitJ->isDominated(*lFitI)) {
				lS[i].push_back(j);  // Add index j to dominated set of i
				++lN[j];             // Increment domination counter of j
			} else if(lFitI->isDominated(*lFitJ)) {
				lS[j].push_back(i);  // Add index i to dominated set of j
				++lN[i];             // Increment domination counter of i
			}
		}
		if(lN[i] == 0) {         // If i is non-dominated
			outParetoFronts.back().push_back(i);
			++lParetoSorted;
		}
	}

	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    uint2ordinal(1)+std::string(" Pareto front consists of ")+
	    uint2str(outParetoFronts.back().size())+" individuals"
	);

	// Continue ranking until individual pool is empty or stop criterion reach
	while((lParetoSorted < inIndividualPool.size()) && (lParetoSorted < inSortStop)) {
		unsigned int lIndexLastFront = outParetoFronts.size() - 1;
		outParetoFronts.resize(outParetoFronts.size() + 1);
		for(unsigned int k=0; k<outParetoFronts[lIndexLastFront].size(); ++k) {
			unsigned int lIndexPk = outParetoFronts[lIndexLastFront][k];
			for(unsigned int l=0; l<lS[lIndexPk].size(); ++l) {
				unsigned int lIndexSl = lS[lIndexPk][l];
				if(--lN[lIndexSl] == 0) {
					outParetoFronts.back().push_back(lIndexSl);
					++lParetoSorted;
				}
			}
		}
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    uint2ordinal(outParetoFronts.size())+std::string(" Pareto front consists of ")+
		    uint2str(outParetoFronts.back().size())+" individuals"
		);
	}
	Beagle_StackTraceEndM();
}
Пример #2
0
/*!
 *  \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();
}