From 1f7c135934b6604c5409d4b6f34861105c0a64cb Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 9 Jul 2012 12:01:50 -0600 Subject: It works well enough to solve polynomial maxima. --- src/explicitsimulation.cpp | 139 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/explicitsimulation.cpp (limited to 'src/explicitsimulation.cpp') diff --git a/src/explicitsimulation.cpp b/src/explicitsimulation.cpp new file mode 100644 index 0000000..281e7e5 --- /dev/null +++ b/src/explicitsimulation.cpp @@ -0,0 +1,139 @@ +#include "genetic/explicitsimulation.h" +#include "genetic/operator.h" +#include "genetic/fitnessfunction.h" + +#include +#include + +using namespace Bu; + +Genetic::ExplicitSimulation::ExplicitSimulation( Genetic::Operator *pOper, + Genetic::FitnessFunction *pFunc, int iPopSize, float fKeep, + float fRandom, bool bKeepBest ) : + pOper( pOper ), + pFunc( pFunc ), + iPopSize( iPopSize ), + fKeep( fKeep ), + fRandom( fRandom ), + bKeepBest( bKeepBest ) +{ + for( int j = 0; j < iPopSize; j++ ) + { + xPop.addPhenotype( pOper->random() ); + } + + updateFitness(); +} + +Genetic::ExplicitSimulation::~ExplicitSimulation() +{ + delete pOper; + delete pFunc; +} + +void Genetic::ExplicitSimulation::timestep() +{ + PhenotypeList lNew; + + int iChildren = iPopSize*(1.0-fKeep-fRandom); + + // Create children + for( int j = 0; j < iChildren; j++ ) + { + PhenotypeList lParents; + for( int k = 0; k < pOper->parentCount(); k++ ) + lParents.append( xPop.getPhenotype( selectWeighted() ) ); + lNew.append( pOper->mate( lParents ) ); + } + + // Select phenotypes for keeping + int iKeep = iPopSize*fKeep; + FitnessHash hTempFitness; + for( int j = 0; j < iKeep; j++ ) + { + Genetic::PhenotypeId id = selectWeighted(); + lNew.append( xPop.takePhenotype( id ) ); + hTempFitness.insert( id, hFitness.get( id ) ); + hFitness.erase( id ); + dTotalFitness -= hTempFitness.get( id ); + } + + if( bKeepBest && hFitness.has( uMaxFitness ) ) + { + lNew.append( xPop.takePhenotype( uMaxFitness ) ); + hTempFitness.insert( uMaxFitness, hFitness.get( uMaxFitness ) ); + hFitness.erase( uMaxFitness ); + dTotalFitness -= hTempFitness.get( uMaxFitness ); + } + + // Fill in the remainder with random phenotypes + while( lNew.getSize() < iPopSize ) + { + lNew.append( pOper->random() ); + } + + // Refill the population + hFitness = hTempFitness; + xPop.clear(); + xPop.timestep(); + for( PhenotypeList::iterator i = lNew.begin(); i; i++ ) + { + xPop.addPhenotype( *i ); + } + + updateFitness(); +} + +Genetic::PhenotypeId Genetic::ExplicitSimulation::selectWeighted() +{ + double dSel = Bu::Random::randNorm()*dTotalFitness; + double dRun = 0.0; + + for( FitnessHash::iterator i = hFitness.begin(); i; i++ ) + { + dRun += *i; + if( dSel < dRun ) + return i.getKey(); + } + + sio << "Genetic::ExplicitSimulation::selectWeighted() - failed, picked max" + << sio.nl; + + return uMaxFitness; +} + +void Genetic::ExplicitSimulation::updateFitness() +{ + dMinFitness = -1.0; + dTotalFitness = 0.0; + for( Population::iterator i = xPop.begin(); i; i++ ) + { + double dFitness; + if( hFitness.has( i.getKey() ) ) + { + dFitness = hFitness.get( i.getKey() ); + } + else + { + dFitness = (*pFunc)( *i ); + if( dFitness < 0.0 ) + dFitness = 0.0; + hFitness.insert( i.getKey(), dFitness ); + } + dTotalFitness += dFitness; + if( dMinFitness < 0.0 ) + { + dMinFitness = dMaxFitness = dFitness; + uMaxFitness = i.getKey(); + } + else if( dMinFitness > dFitness ) + { + dMinFitness = dFitness; + } + else if( dMaxFitness < dFitness ) + { + dMaxFitness = dFitness; + uMaxFitness = i.getKey(); + } + } +} -- cgit v1.2.3