#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(); } } }