COSC_4P82_Assignment_1/lib/beagle-3.0.3/beagle/Coev/src/EvaluationOp.cpp

329 lines
12 KiB
C++

/*
* Open BEAGLE
* Copyright (C) 2001-2007 by Christian Gagne and Marc Parizeau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact:
* Laboratoire de Vision et Systemes Numeriques
* Departement de genie electrique et de genie informatique
* Universite Laval, Quebec, Canada, G1K 7P4
* http://vision.gel.ulaval.ca
*
*/
/*!
* \file beagle/Coev/src/EvaluationOp.cpp
* \brief Source code of class Coev::EvaluationOp.
* \author Christian Gagne
* \author Marc Parizeau
* $Revision: 1.18.2.1 $
* $Date: 2007/05/09 01:51:01 $
*/
#include "beagle/Coev.hpp"
#include <string>
using namespace Beagle;
/*
* Initialize static evaluation operator evaluation condition.
*/
PACC::Threading::Condition Coev::EvaluationOp::smCondition;
/*
* Initialize static evaluation operator sets stack.
*/
Coev::EvaluationOp::EvalSetVector Coev::EvaluationOp::smEvalSets;
/*
* Initialize static evaluation operator trigger.
*/
unsigned int Coev::EvaluationOp::smTrigger = 0;
/*!
* \brief Construct an evaluation set.
*/
Coev::EvaluationOp::EvalSet::EvalSet() :
mID(0)
{ }
/*!
* \brief Construct an evaluation set.
* \param inIndividuals Individual bag of the evaluation set.
* \param inContext Evolutionary context.
* \param inID ID of the evaluation set, for convenience purpuse, not used internally.
*/
Coev::EvaluationOp::EvalSet::EvalSet(Individual::Bag& inIndividuals,
Context::Handle inContext,
unsigned int inID) :
mIndividuals(inIndividuals),
mContext(inContext),
mID(inID)
{ }
/*!
* \brief Construct a co-evolutionary evaluation operator.
* \param inTrigger Number of sets to accumulate before triggering evaluation procedure.
* \param inName Name of the co-evolutionary evaluation operator.
*/
Coev::EvaluationOp::EvaluationOp(unsigned int inTrigger, Beagle::string inName) :
Beagle::EvaluationOp(inName)
{
Beagle_StackTraceBeginM();
smCondition.lock();
if(smTrigger == 0) smTrigger = inTrigger;
else if(inTrigger != smTrigger) {
std::ostringstream lOSS;
lOSS << "trigger value given as argument to constructor of Coev::EvaluationOp (";
lOSS << inTrigger << ") is different from the actual non-zero value of the trigger (";
lOSS << smTrigger << ")!";
smCondition.unlock();
throw Beagle_RunTimeExceptionM(lOSS.str().c_str());
}
smCondition.unlock();
Beagle_StackTraceEndM("Coev::EvaluationOp::EvaluationOp(unsigned int inTrigger, string inName)");
}
/*!
* \brief Add evaluation set into shared structure.
* \param inEvalSet Evaluation set to add.
* \param inBlocking If true, the add set operation block until fitness evaluation is done.
*/
void Coev::EvaluationOp::addSet(EvalSet& inEvalSet, bool inBlocking)
{
Beagle_StackTraceBeginM();
smCondition.lock();
if(smTrigger == 0) {
smCondition.unlock();
throw Beagle_RunTimeExceptionM("co-evolution trigger value is zero!");
}
if(smEvalSets.size() >= smTrigger) {
std::ostringstream lOSS;
lOSS << "number of evaluation sets in co-evolution evaluation operator (";
lOSS << smEvalSets.size() << ") is equal or bigger than the trigger value (";
lOSS << smTrigger << ")!";
smCondition.unlock();
throw Beagle_RunTimeExceptionM(lOSS.str().c_str());
}
// Add evaluation set
smEvalSets.push_back(inEvalSet);
// If all needed evaluation sets are added
if(smEvalSets.size() == smTrigger) {
evaluateSets(smEvalSets);
smEvalSets.clear();
smCondition.broadcast();
}
// Othewize, wait to get all needed evaluation sets
else if(inBlocking) {
smCondition.wait();
}
smCondition.unlock();
Beagle_StackTraceEndM("void Coev::EvaluationOp::addSet(EvalSet& inEvalSet, bool inBlocking)");
}
/*!
* \brief Set fitness value of an individual.
* \param inFitness New fitness value of the individual.
* \param ioIndividual Individual which fitness value is set.
* \param ioContext Evolutionary context.
*/
void Coev::EvaluationOp::assignFitness(Fitness::Handle inFitness,
Individual& ioIndividual,
Context& ioContext) const
{
Beagle_StackTraceBeginM();
ioIndividual.setFitness(inFitness);
inFitness->setValid();
ioContext.setProcessedDeme(ioContext.getProcessedDeme()+1);
ioContext.setTotalProcessedDeme(ioContext.getTotalProcessedDeme()+1);
ioContext.setProcessedVivarium(ioContext.getProcessedVivarium()+1);
ioContext.setTotalProcessedVivarium(ioContext.getTotalProcessedVivarium()+1);
Beagle_StackTraceEndM("void Coev::EvaluationOp::assignFitness(Fitness::Handle inFitness, Individual& ioIndividual, Context& ioContext) const");
}
/*!
* \brief Apply the evaluation operation on a breeding pool, returning a evaluated bred individual.
* \param inBreedingPool Breeding pool to use for the breeding operation.
* \param inChild Node handle associated to child node in the breeder tree.
* \param ioContext Evolutionary context of the breeding operation.
* \return Evaluated bred individual.
*/
Individual::Handle Coev::EvaluationOp::breed(Individual::Bag& inBreedingPool,
BreederNode::Handle inChild,
Context& ioContext)
{
Beagle_StackTraceBeginM();
Beagle_NonNullPointerAssertM(inChild);
Deme& lDeme = *ioContext.getDemeHandle();
if(lDeme.getStats()->isValid()) {
ioContext.setProcessedDeme(0);
if((ioContext.getGeneration()!=0) && (lDeme.getStats()->existItem("total-processed"))) {
ioContext.setTotalProcessedDeme((unsigned int)lDeme.getStats()->getItem("total-processed"));
}
else ioContext.setTotalProcessedDeme(0);
lDeme.getStats()->setInvalid();
if(ioContext.getDemeIndex()==0) {
Stats& lVivaStats = *ioContext.getVivarium().getStats();
ioContext.setProcessedVivarium(0);
if((ioContext.getGeneration()!=0) && (lVivaStats.existItem("total-processed"))) {
ioContext.setTotalProcessedVivarium((unsigned int)lVivaStats.getItem("total-processed"));
}
else ioContext.setTotalProcessedVivarium(0);
lVivaStats.setInvalid();
}
}
Beagle_NonNullPointerAssertM(inChild);
Beagle_NonNullPointerAssertM(inChild->getBreederOp());
Individual::Handle lBredIndividual =
inChild->getBreederOp()->breed(inBreedingPool, inChild->getFirstChild(), ioContext);
if((lBredIndividual->getFitness()==NULL) || (lBredIndividual->getFitness()->isValid()==false)) {
Beagle_LogVerboseM(
ioContext.getSystem().getLogger(),
"evaluation", "Beagle::Coev::EvaluationOp",
"Evaluating the fitness of a new bred individual"
);
Individual::Bag lNonEvalIndiv;
lNonEvalIndiv.push_back(lBredIndividual);
Context::Handle lContext = &ioContext;
makeSets(lNonEvalIndiv, lContext);
Beagle_LogVerboseM(
ioContext.getSystem().getLogger(),
"evaluation", "Beagle::Coev::EvaluationOp",
string("The individual fitness value is: ")+
lBredIndividual->getFitness()->serialize()
);
if(mDemeHOFSize->getWrappedValue() > 0) {
Beagle_LogVerboseM(
ioContext.getSystem().getLogger(),
"evaluation", "Beagle::Coev::EvaluationOp",
"Updating the deme hall-of-fame"
);
lDeme.getHallOfFame().updateWithIndividual(mDemeHOFSize->getWrappedValue(),
*lBredIndividual, ioContext);
}
if(mVivaHOFSize->getWrappedValue() > 0) {
Beagle_LogVerboseM(
ioContext.getSystem().getLogger(),
"evaluation", "Beagle::Coev::EvaluationOp",
"Updating the vivarium hall-of-fame"
);
ioContext.getVivarium().getHallOfFame().updateWithIndividual(mVivaHOFSize->getWrappedValue(),
*lBredIndividual, ioContext);
}
}
return lBredIndividual;
Beagle_StackTraceEndM("Individual::Handle Coev::EvaluationOp::breed(Individual::Bag& inBreedingPool, BreederNode::Handle inChild, Context& ioContext)");
}
/*!
* \brief Evaluating an individual in co-evolution is not that simple. Define makeSets and
* evaluateSets methods instead.
*/
Fitness::Handle Coev::EvaluationOp::evaluate(Individual& inIndividual, Context& ioContext)
{
Beagle_StackTraceBeginM();
throw Beagle_UndefinedMethodInternalExceptionM("evaluate","Coev::EvaluationOp",getName());
Beagle_StackTraceEndM("Fitness::Handle Coev::EvaluationOp::evaluate(Individual& inIndividual, Context& ioContext)");
}
/*!
* \brief Apply co-evolutionary evaluation operation on the deme.
* \param ioDeme Deme to evaluate fitness.
* \param ioContext Evolutionary context.
*/
void Coev::EvaluationOp::operate(Deme& ioDeme, Context& ioContext)
{
Beagle_StackTraceBeginM();
Beagle_LogTraceM(
ioContext.getSystem().getLogger(),
"evaluation", "Beagle::Coev::EvaluationOp",
string("Evaluating the individuals fitness of the ")+
uint2ordinal(ioContext.getDemeIndex()+1)+" deme in co-evolution mode"
);
ioContext.setProcessedDeme(0);
if((ioContext.getGeneration()!=0) && (ioDeme.getStats()->existItem("total-processed"))) {
ioContext.setTotalProcessedDeme((unsigned int)ioDeme.getStats()->getItem("total-processed"));
}
else ioContext.setTotalProcessedDeme(0);
ioDeme.getStats()->setInvalid();
if(ioContext.getDemeIndex()==0) {
Stats& lVivaStats = *ioContext.getVivarium().getStats();
ioContext.setProcessedVivarium(0);
if((ioContext.getGeneration()!=0) && (lVivaStats.existItem("total-processed"))) {
ioContext.setTotalProcessedVivarium((unsigned int)lVivaStats.getItem("total-processed"));
}
else ioContext.setTotalProcessedVivarium(0);
lVivaStats.setInvalid();
}
Beagle_LogVerboseM(
ioContext.getSystem().getLogger(),
"evaluation", "Beagle::Coev::EvaluationOp",
string("Calling co-evolution evaluation hook for the ")+
uint2ordinal(ioContext.getDemeIndex()+1)+" deme"
);
Context::Handle lContext = &ioContext;
makeSets(ioDeme, lContext);
if(mDemeHOFSize->getWrappedValue() > 0) {
Beagle_LogDetailedM(
ioContext.getSystem().getLogger(),
"evaluation", "Beagle::Coev::EvaluationOp",
"Updating the deme's hall-of-fame"
);
ioDeme.getHallOfFame().updateWithDeme(mDemeHOFSize->getWrappedValue(), ioDeme, ioContext);
ioDeme.getHallOfFame().log(Logger::eVerbose, ioContext);
}
if(mVivaHOFSize->getWrappedValue() > 0) {
Beagle_LogDetailedM(
ioContext.getSystem().getLogger(),
"evaluation", "Beagle::Coev::EvaluationOp",
"Updating the vivarium's hall-of-fame"
);
ioContext.getVivarium().getHallOfFame().updateWithDeme(mVivaHOFSize->getWrappedValue(),
ioDeme, ioContext);
ioContext.getVivarium().getHallOfFame().log(Logger::eVerbose, ioContext);
}
Beagle_StackTraceEndM("void Coev::EvaluationOp::operate(Deme& ioDeme, Context& ioContext)");
}