예제 #1
0
/*!
 *  \brief Interpret the GP individual.
 *  \param outResult Datum containing the result of the interpretation.
 *  \param ioContext GP evolutionary context.
 *  \throw Beagle::ObjectException When individual or tree are empty.
 *  \throw Beagle::AssertException When context is not correctly set.
 *  \throw Beagle::GP::MaxNodesExecutionException If number of nodes execution is more than allowed.
 *  \throw Beagle::GP::MaxTimeExecutionException If elapsed execution time is more than allowed.
 */
void GP::Individual::run(GP::Datum& outResult, GP::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	if(&ioContext.getIndividual() != this) {
		std::ostringstream lOSS;
		lOSS << "In GP::Individual::run():  For the given context, ";
		lOSS << "getIndividual() did not return the same individual as was passed to this (run) ";
		lOSS << "method. Consider setting the context's individual to be the same by using the ";
		lOSS << "method Context::setIndividualHandle().";
		throw Beagle_RunTimeExceptionM(lOSS.str());
	}
	if(empty()) throw Beagle_ObjectExceptionM("Could not interpret, individual has no trees!");
	if((*this)[0]->empty()) throw Beagle_ObjectExceptionM("Could not interpret, 1st tree is empty!");
	Tree::Handle lOldTreeHandle = ioContext.getGenotypeHandle();
	unsigned int lOldTreeIndex  = ioContext.getGenotypeIndex();
	ioContext.setGenotypeIndex(0);
	ioContext.setGenotypeHandle((*this)[0]);
	Beagle_LogVerboseM(
	    ioContext.getSystem().getLogger(),
	    std::string("Running the ")+uint2ordinal(ioContext.getIndividualIndex()+1)+
	    std::string(" individual")
	);
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    std::string("The individual is: ")
	);
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    (*this)
	);
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    std::string("Executing the first tree root node '")+
	    (*(*this)[0])[0].mPrimitive->getName()+"'"
	);
	ioContext.setNodesExecutionCount(0);
	ioContext.incrementNodesExecuted();
	ioContext.getExecutionTimer().reset();
	ioContext.pushCallStack(0);
	(*(*this)[0])[0].mPrimitive->execute(outResult, ioContext);
	ioContext.popCallStack();
	ioContext.checkExecutionTime();
	Beagle_LogDebugM(
	    ioContext.getSystem().getLogger(),
	    std::string("Result of executing the ")+uint2ordinal(ioContext.getIndividualIndex()+1)+
	    std::string(" individual: ")+outResult.serialize()
	);
	ioContext.setGenotypeIndex(lOldTreeIndex);
	ioContext.setGenotypeHandle(lOldTreeHandle);
	Beagle_StackTraceEndM();
}
예제 #2
0
/*!
 *  \brief Validate the GP individual.
 *  \param ioContext Evolutionary context.
 *  \return True if the GP individual is valid, false if not.
 */
bool GP::Individual::validate(GP::Context& ioContext)
{
	Beagle_StackTraceBeginM();
	bool lResult = true;

	Beagle_LogDetailedM(
	    ioContext.getSystem().getLogger(),
	    std::string("Validating ")+uint2ordinal(ioContext.getIndividualIndex()+1)+
	    std::string(" individual")
	);

	// Store original values.
	GP::Tree::Handle lOldTreeHandle = ioContext.getGenotypeHandle();
	unsigned int lOldTreeIndex = ioContext.getGenotypeIndex();

	// Loop through each of the trees in the individual
	for (unsigned int i=0; i<size(); i++) {
		GP::Tree::Handle lTree = (*this)[i];
		if (lTree == NULL) {
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    std::string("Skipping ")+uint2ordinal(i+1)+std::string(" tree because it's NULL-valued")
			);
			continue;
		}

		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    std::string("Validating ")+uint2ordinal(i+1)+std::string(" tree")
		);

		// Store the new values
		ioContext.setGenotypeHandle(lTree);
		ioContext.setGenotypeIndex(i);

		lTree->setContextToNode(0, ioContext);
		if(!lTree->validateSubTree(0, ioContext)) {
			Beagle_LogVerboseM(
			    ioContext.getSystem().getLogger(),
			    std::string("Validation of ")+uint2ordinal(i+1)+std::string(" tree failed.")
			);
			lResult = false;
			break;
		}
	}

	if(lResult) {
		Beagle_LogVerboseM(
		    ioContext.getSystem().getLogger(),
		    std::string("Individual passed validation testing.")
		);
	}

	// Restore the original values.
	ioContext.setGenotypeHandle(lOldTreeHandle);
	ioContext.setGenotypeIndex(lOldTreeIndex);

	return lResult;
	Beagle_StackTraceEndM();
}
/*!
 *  \brief Evaluate the individual fitness.
 *  \param inIndividual Individual to evaluate.
 *  \param ioContext Evolutionary context.
 *  \return Handle to the fitness measure.
 */
Fitness::Handle SharedLibEvalOp::evaluate(GP::Individual& inIndividual, GP::Context& ioContext)
{
    Beagle_StackTraceBeginM();

    std::ostringstream lOSS;
    lOSS << "Evaluating individual " << ioContext.getIndividualIndex() << ", deme ";
    lOSS << ioContext.getDemeIndex() << ", generation " << ioContext.getGeneration(); 
    Beagle_LogDebugM(ioContext.getSystem().getLogger(), "evaluate", "Beagle::GP::SpamebaseEvalOp", lOSS.str());

    GP::PrimitiveSuperSet::Handle lPrimitiveSuperSet= 
        castHandleT<GP::PrimitiveSuperSet>(ioContext.getSystem().getComponent("GP-PrimitiveSuperSet"));
    GP::PrimitiveSet::Handle lPrimitiveSet= (*lPrimitiveSuperSet)[0];

    // Get a handle on the shared library used for evaluation.
    // TODO: Open shared lib only once per generation!
    this->mTimer.reset();
    if (this->mSharedLibHandle)
    {
        dlclose(this->mSharedLibHandle);
        Beagle_LogDebugM(
            ioContext.getSystem().getLogger(), "evaluate", "Beagle::GP::SpamebaseEvalOp", 
            "Closed previously opened shared lib.");
    }
    if (!ioContext.getSystem().getRegister().isRegistered("icu.compiler.lib-path"))
    {
        throw Beagle_RunTimeExceptionM("Parameter icu.compiler.lib-path not found in registry; make sure to apply SharedLibCompilerOp before applying SharedLibEvalOp.");    
    }
    std::string lLibName= castHandleT<String>(ioContext.getSystem().getRegister()["icu.compiler.lib-path"])->getWrappedValue();
    this->mSharedLibHandle= dlopen((const char*)lLibName.c_str(), RTLD_LAZY);
    if (!this->mSharedLibHandle) 
    {
        throw Beagle_RunTimeExceptionM("Cannot open shared library "+ lLibName+ ": "+ dlerror()+ ".");
    }
    dlerror();

    // Draw a sample from the data set to construct the training set.
    
    this->mTimer.reset();
	// Get a handle on D, S, and L.
    DataSetBinaryClassification::Handle lDataSet= castHandleT<DataSetBinaryClassification>(ioContext.getSystem().getComponent("DataSet"));
    std::vector<unsigned int>* lIndexesPositives= lDataSet->getIndexesPositives();
    std::vector<unsigned int>* lIndexesNegatives= lDataSet->getIndexesNegatives();
    int lNrSamplesPositive= castHandleT<Int>(ioContext.getSystem().getRegister()["icu.trainingset.size-pos"])->getWrappedValue();
    int lNrSamplesNegative= castHandleT<Int>(ioContext.getSystem().getRegister()["icu.trainingset.size-neg"])->getWrappedValue();
    
    // Shuffle both negative and positive indexes.
    std::random_shuffle(lIndexesPositives->begin(), lIndexesPositives->end(), ioContext.getSystem().getRandomizer());
    std::random_shuffle(lIndexesNegatives->begin(), lIndexesNegatives->end(), ioContext.getSystem().getRandomizer());
    
    // Nr of columns in each row in the dataset.
    int lNrColumns= castHandleT<Int>(ioContext.getSystem().getRegister()["icu.dataset.columns"])->getWrappedValue();
    
    double lTimeInit= this->mTimer.getValue();
    this->mTimer.reset();

    // Evaluate sampled test cases
    unsigned int lTruePositives = 0;
    unsigned int lTrueNegatives = 0;
    unsigned int lFalsePositives= 0;
    unsigned int lFalseNegatives= 0;
    int (*apply_individual)(float[])= 0;
    float lValues[lNrColumns];
    std::vector<unsigned int>::iterator lLastIndex= lIndexesPositives->begin()+ lNrSamplesPositive;


    // Positives.
    for(std::vector<unsigned int>::const_iterator lIndex=lIndexesPositives->begin(); lIndex!=lLastIndex; ++lIndex)
    {
        const Beagle::Vector& lData = (*lDataSet)[*lIndex].second;
        std::ostringstream lFunctionName;
        lFunctionName << "apply_individual_";
        lFunctionName << ioContext.getGeneration() << "_" << ioContext.getDemeIndex() << "_" << ioContext.getIndividualIndex();
        apply_individual= (int(*)(float*))dlsym(this->mSharedLibHandle, lFunctionName.str().c_str());
        char* lError= 0;
        if ((lError = dlerror()) != NULL) {
            throw Beagle_RunTimeExceptionM("Error loading function "+ lFunctionName.str()+ ": "+ lError+ ".");
        }
        for(unsigned int j=0; j<lData.size(); ++j) {
            lValues[j]= Float(lData[j]);
        }		
        bool lResult= apply_individual(lValues);
        (lResult == 1) ? lTruePositives++ : lFalseNegatives++;
    }
    // Negatives.
    lLastIndex= lIndexesNegatives->begin()+ lNrSamplesNegative;
    for(std::vector<unsigned int>::const_iterator lIndex=lIndexesNegatives->begin(); lIndex!=lLastIndex; ++lIndex)
    {
        const Beagle::Vector& lData = (*lDataSet)[*lIndex].second;
        std::ostringstream lFunctionName;
        lFunctionName << "apply_individual_";
        lFunctionName << ioContext.getGeneration() << "_" << ioContext.getDemeIndex() << "_" << ioContext.getIndividualIndex();
        apply_individual= (int(*)(float*))dlsym(this->mSharedLibHandle, lFunctionName.str().c_str());
        char* lError= 0;
        if ((lError = dlerror()) != NULL) {
            throw Beagle_RunTimeExceptionM("Error loading function "+ lFunctionName.str()+ ": "+ lError+ ".");
        }
        for(unsigned int j=0; j<lData.size(); ++j) {
            lValues[j]= Float(lData[j]);
        }		
        bool lResult= apply_individual(lValues);
        (lResult == 0) ? lTrueNegatives++ : lFalsePositives++;
    }


    double lTimeEvaluate= this->mTimer.getValue();

    {
        using namespace std;
        ostringstream lOSS;
        lOSS << "g" << ioContext.getGeneration();
        lOSS << " d" << ioContext.getDemeIndex();
        lOSS << " i" << ioContext.getIndividualIndex() << ", ";
        lOSS << "TP|FP|FN|TN = ";
        lOSS.width(7);
        lOSS << right << lTruePositives << "|";
        lOSS.width(7);
        lOSS << right << lFalsePositives << "|";
        lOSS.width(7);
        lOSS << right << lFalseNegatives << "|";
        lOSS.width(7);
        lOSS << right << lTrueNegatives;
        Beagle_LogDetailedM(ioContext.getSystem().getLogger(), "evaluate", "Beagle::GP::SharedLibEvalOp", lOSS.str());
    }

    GP::FitnessMCC* fitness= new GP::FitnessMCC(lTruePositives, lFalsePositives, lTrueNegatives, lFalseNegatives);

    return fitness;

    Beagle_StackTraceEndM("SharedLibEvalOp::evaluate(GP::Individual& inIndividual, GP::Context& ioContext)");
}