예제 #1
0
/*!
 *  \brief Apply the recombination operation on a breeding pool, returning a recombined individual.
 *  \param inBreedingPool Breeding pool to use for the recombination operation.
 *  \param inChild Node handle associated to child node in the breeder tree.
 *  \param ioContext Evolutionary context of the recombination operation.
 *  \return Recombined individual.
 */
Individual::Handle RecombinationOp::breed(Individual::Bag& inBreedingPool,
        BreederNode::Handle inChild,
        Context& ioContext)
{
	Beagle_StackTraceBeginM();

	// Generate parents for recombination.
	Individual::Bag::Handle lParents = new Individual::Bag;
	if(inChild == NULL) {
		const unsigned int lNbGenerated =
		    (mNumberRecomb->getWrappedValue()==0) ? inBreedingPool.size() :
		    minOf<unsigned int>(inBreedingPool.size(), mNumberRecomb->getWrappedValue());
		if(lNbGenerated == inBreedingPool.size()) (*lParents) = inBreedingPool;
		else {
			std::vector<unsigned int> lIndices(inBreedingPool.size());
			for(unsigned int i=0; i<lIndices.size(); ++i) lIndices[i] = i;
			std::random_shuffle(lIndices.begin(), lIndices.end(),
			                    ioContext.getSystem().getRandomizer());
			for(unsigned int i=0; i<lNbGenerated; ++i) {
				lParents->push_back(inBreedingPool[lIndices[i]]);
			}
		}
	} else {
		Beagle_NonNullPointerAssertM(inChild->getBreederOp());
		const unsigned int lNbGenerated =
		    (mNumberRecomb->getWrappedValue()==0) ? inBreedingPool.size() :
		    minOf<unsigned int>(inBreedingPool.size(), mNumberRecomb->getWrappedValue());
		for(unsigned int i=0; i<lNbGenerated; ++i) {
			Individual::Handle lIndiv = inChild->getBreederOp()->breed(inBreedingPool,
			                            inChild->getFirstChild(),
			                            ioContext);
			lParents->push_back(lIndiv);
		}
	}

	// Log parents selected for recombination.
	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    std::string("Recombining ")+uint2str(lParents->size())+std::string(" individuals together")
	);

	// Do recombination operation on parent and get the resulting child.
	Individual::Handle lChildIndiv = recombine(*lParents, ioContext);
	if(lChildIndiv->getFitness() != NULL) {
		lChildIndiv->getFitness()->setInvalid();
	}

	// Log information to history, if it is used.
	History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History"));
	if(lHistory != NULL) {
		std::vector<HistoryID> lParentNames;
		for(unsigned int i=0; i<lParents->size(); ++i) {
			HistoryID::Handle lHID = castHandleT<HistoryID>(lParents->at(i)->getMember("HistoryID"));
			if(lHID != NULL) lParentNames.push_back(*lHID);
		}
		lHistory->incrementHistoryVar(*lChildIndiv);
		lHistory->trace(ioContext, lParentNames, lChildIndiv, getName(), "recombination");
	}

	return lChildIndiv;
	Beagle_StackTraceEndM();
}
예제 #2
0
/*!
 *  \brief Apply the recombination operation on the deme.
 *  \param ioDeme Current deme of individuals to recombine.
 *  \param ioContext Context of the evolution.
 */
void RecombinationOp::operate(Deme& ioDeme, Context& ioContext)
{
	Beagle_StackTraceBeginM();
	Beagle_ValidateParameterM(mRecombProba->getWrappedValue()>=0.0, mRecombProbaName, "<0");

	Beagle_LogTraceM(
	    ioContext.getSystem().getLogger(),
	    std::string("Recombining individuals of the ")+
	    uint2ordinal(ioContext.getDemeIndex()+1)+" deme"
	);
	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    std::string("Recombining individuals with probability ")+
	    dbl2str(mRecombProba->getWrappedValue())
	);

	History::Handle lHistory = castHandleT<History>(ioContext.getSystem().haveComponent("History"));
	Individual::Bag lRecombinedIndiv(ioDeme.size());
	for(unsigned int i=0; i<lRecombinedIndiv.size(); ++i) {
		if(ioContext.getSystem().getRandomizer().rollUniform() <= mRecombProba->getWrappedValue()) {
			Individual::Bag::Handle lParents = new Individual::Bag;
			const unsigned int lNbGenerated =
			    (mNumberRecomb->getWrappedValue()==0) ? ioDeme.size() :
			    minOf<unsigned int>(ioDeme.size(), mNumberRecomb->getWrappedValue());
			if(lNbGenerated == ioDeme.size()) (*lParents) = ioDeme;
			else {
				std::vector<unsigned int> lIndices(ioDeme.size());
				for(unsigned int j=0; j<lIndices.size(); ++j) lIndices[j] = j;
				std::random_shuffle(lIndices.begin(), lIndices.end(),
				                    ioContext.getSystem().getRandomizer());
				for(unsigned int j=0; j<lNbGenerated; ++j) {
					lParents->push_back(ioDeme[lIndices[j]]);
				}
			}
			lRecombinedIndiv[i] = recombine(*lParents, ioContext);
			if(lRecombinedIndiv[i]->getFitness() != NULL) {
				lRecombinedIndiv[i]->getFitness()->setInvalid();
			}
			// Log and update history.
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    std::string("The ")+uint2ordinal(i+1)+
			    std::string(" individual as been replaced by recombination")
			);
			if(lHistory != NULL) {
				std::vector<HistoryID> lParentNames;
				for(unsigned int j=0; j<lParents->size(); ++j) {
					HistoryID::Handle lHID = castHandleT<HistoryID>(lParents->at(j)->getMember("HistoryID"));
					if(lHID != NULL) lParentNames.push_back(*lHID);
				}
				lHistory->incrementHistoryVar(*lRecombinedIndiv[i]);
				lHistory->trace(ioContext, lParentNames, lRecombinedIndiv[i], getName(), "recombination");
			}
		}
	}
	for(unsigned int i=0; i<ioDeme.size(); ++i) {
		if(lRecombinedIndiv[i] != NULL) ioDeme[i] = lRecombinedIndiv[i];
	}

	Beagle_StackTraceEndM();
}