diff options
| -rw-r--r-- | src/explicitsimulation.cpp | 130 | ||||
| -rw-r--r-- | src/explicitsimulation.h | 35 | ||||
| -rw-r--r-- | src/fitnessfunction.h | 1 | ||||
| -rw-r--r-- | src/tests/maxima/fitnessfunctioneq.cpp | 5 | ||||
| -rw-r--r-- | src/tests/maxima/fitnessfunctioneq.h | 1 | ||||
| -rw-r--r-- | src/tests/maxima/main.cpp | 1 |
6 files changed, 146 insertions, 27 deletions
diff --git a/src/explicitsimulation.cpp b/src/explicitsimulation.cpp index 281e7e5..6a9356b 100644 --- a/src/explicitsimulation.cpp +++ b/src/explicitsimulation.cpp | |||
| @@ -1,17 +1,21 @@ | |||
| 1 | #include "genetic/explicitsimulation.h" | 1 | #include "genetic/explicitsimulation.h" |
| 2 | #include "genetic/operator.h" | 2 | #include "genetic/operator.h" |
| 3 | #include "genetic/fitnessfunction.h" | 3 | #include "genetic/fitnessfunction.h" |
| 4 | #include "genetic/phenotype.h" | ||
| 4 | 5 | ||
| 5 | #include <bu/random.h> | 6 | #include <bu/random.h> |
| 6 | #include <bu/sio.h> | 7 | #include <bu/sio.h> |
| 8 | #include <bu/mutexlocker.h> | ||
| 9 | |||
| 10 | #include <stdlib.h> | ||
| 7 | 11 | ||
| 8 | using namespace Bu; | 12 | using namespace Bu; |
| 9 | 13 | ||
| 10 | Genetic::ExplicitSimulation::ExplicitSimulation( Genetic::Operator *pOper, | 14 | Genetic::ExplicitSimulation::ExplicitSimulation( Genetic::Operator *pOper, |
| 11 | Genetic::FitnessFunction *pFunc, int iPopSize, float fKeep, | 15 | Genetic::FitnessFunction *pFunc, int iThreads, int iPopSize, |
| 12 | float fRandom, bool bKeepBest ) : | 16 | float fKeep, float fRandom, bool bKeepBest ) : |
| 13 | pOper( pOper ), | 17 | pOper( pOper ), |
| 14 | pFunc( pFunc ), | 18 | //pFunc( pFunc ), |
| 15 | iPopSize( iPopSize ), | 19 | iPopSize( iPopSize ), |
| 16 | fKeep( fKeep ), | 20 | fKeep( fKeep ), |
| 17 | fRandom( fRandom ), | 21 | fRandom( fRandom ), |
| @@ -22,13 +26,30 @@ Genetic::ExplicitSimulation::ExplicitSimulation( Genetic::Operator *pOper, | |||
| 22 | xPop.addPhenotype( pOper->random() ); | 26 | xPop.addPhenotype( pOper->random() ); |
| 23 | } | 27 | } |
| 24 | 28 | ||
| 29 | if( iThreads < 1 ) | ||
| 30 | iThreads = 1; | ||
| 31 | |||
| 32 | int iId = 0; | ||
| 33 | lProcessor.append( new Processor( *this, pFunc, qWork, iId++ ) ); | ||
| 34 | while( lProcessor.getSize() < iThreads ) | ||
| 35 | lProcessor.append( | ||
| 36 | new Processor( *this, pFunc->clone(), qWork, iId++ ) | ||
| 37 | ); | ||
| 38 | |||
| 25 | updateFitness(); | 39 | updateFitness(); |
| 26 | } | 40 | } |
| 27 | 41 | ||
| 28 | Genetic::ExplicitSimulation::~ExplicitSimulation() | 42 | Genetic::ExplicitSimulation::~ExplicitSimulation() |
| 29 | { | 43 | { |
| 30 | delete pOper; | 44 | delete pOper; |
| 31 | delete pFunc; | 45 | |
| 46 | for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) | ||
| 47 | (*i)->setRunning( false ); | ||
| 48 | for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) | ||
| 49 | { | ||
| 50 | (*i)->join(); | ||
| 51 | delete *i; | ||
| 52 | } | ||
| 32 | } | 53 | } |
| 33 | 54 | ||
| 34 | void Genetic::ExplicitSimulation::timestep() | 55 | void Genetic::ExplicitSimulation::timestep() |
| @@ -52,12 +73,15 @@ void Genetic::ExplicitSimulation::timestep() | |||
| 52 | for( int j = 0; j < iKeep; j++ ) | 73 | for( int j = 0; j < iKeep; j++ ) |
| 53 | { | 74 | { |
| 54 | Genetic::PhenotypeId id = selectWeighted(); | 75 | Genetic::PhenotypeId id = selectWeighted(); |
| 76 | mFitness.lock(); | ||
| 55 | lNew.append( xPop.takePhenotype( id ) ); | 77 | lNew.append( xPop.takePhenotype( id ) ); |
| 56 | hTempFitness.insert( id, hFitness.get( id ) ); | 78 | hTempFitness.insert( id, hFitness.get( id ) ); |
| 57 | hFitness.erase( id ); | 79 | hFitness.erase( id ); |
| 58 | dTotalFitness -= hTempFitness.get( id ); | 80 | dTotalFitness -= hTempFitness.get( id ); |
| 81 | mFitness.unlock(); | ||
| 59 | } | 82 | } |
| 60 | 83 | ||
| 84 | mFitness.lock(); | ||
| 61 | if( bKeepBest && hFitness.has( uMaxFitness ) ) | 85 | if( bKeepBest && hFitness.has( uMaxFitness ) ) |
| 62 | { | 86 | { |
| 63 | lNew.append( xPop.takePhenotype( uMaxFitness ) ); | 87 | lNew.append( xPop.takePhenotype( uMaxFitness ) ); |
| @@ -65,6 +89,7 @@ void Genetic::ExplicitSimulation::timestep() | |||
| 65 | hFitness.erase( uMaxFitness ); | 89 | hFitness.erase( uMaxFitness ); |
| 66 | dTotalFitness -= hTempFitness.get( uMaxFitness ); | 90 | dTotalFitness -= hTempFitness.get( uMaxFitness ); |
| 67 | } | 91 | } |
| 92 | mFitness.unlock(); | ||
| 68 | 93 | ||
| 69 | // Fill in the remainder with random phenotypes | 94 | // Fill in the remainder with random phenotypes |
| 70 | while( lNew.getSize() < iPopSize ) | 95 | while( lNew.getSize() < iPopSize ) |
| @@ -73,7 +98,9 @@ void Genetic::ExplicitSimulation::timestep() | |||
| 73 | } | 98 | } |
| 74 | 99 | ||
| 75 | // Refill the population | 100 | // Refill the population |
| 101 | mFitness.lock(); | ||
| 76 | hFitness = hTempFitness; | 102 | hFitness = hTempFitness; |
| 103 | mFitness.unlock(); | ||
| 77 | xPop.clear(); | 104 | xPop.clear(); |
| 78 | xPop.timestep(); | 105 | xPop.timestep(); |
| 79 | for( PhenotypeList::iterator i = lNew.begin(); i; i++ ) | 106 | for( PhenotypeList::iterator i = lNew.begin(); i; i++ ) |
| @@ -86,6 +113,8 @@ void Genetic::ExplicitSimulation::timestep() | |||
| 86 | 113 | ||
| 87 | Genetic::PhenotypeId Genetic::ExplicitSimulation::selectWeighted() | 114 | Genetic::PhenotypeId Genetic::ExplicitSimulation::selectWeighted() |
| 88 | { | 115 | { |
| 116 | Bu::MutexLocker ml( mFitness ); | ||
| 117 | |||
| 89 | double dSel = Bu::Random::randNorm()*dTotalFitness; | 118 | double dSel = Bu::Random::randNorm()*dTotalFitness; |
| 90 | double dRun = 0.0; | 119 | double dRun = 0.0; |
| 91 | 120 | ||
| @@ -98,42 +127,93 @@ Genetic::PhenotypeId Genetic::ExplicitSimulation::selectWeighted() | |||
| 98 | 127 | ||
| 99 | sio << "Genetic::ExplicitSimulation::selectWeighted() - failed, picked max" | 128 | sio << "Genetic::ExplicitSimulation::selectWeighted() - failed, picked max" |
| 100 | << sio.nl; | 129 | << sio.nl; |
| 130 | sio << " " << dMinFitness << " - " << dMaxFitness << " -- " << dTotalFitness << " > " << dRun << " > " << dSel << sio.nl; | ||
| 131 | abort(); | ||
| 101 | 132 | ||
| 102 | return uMaxFitness; | 133 | return uMaxFitness; |
| 103 | } | 134 | } |
| 104 | 135 | ||
| 105 | void Genetic::ExplicitSimulation::updateFitness() | 136 | void Genetic::ExplicitSimulation::updateFitness() |
| 106 | { | 137 | { |
| 138 | mFitness.lock(); | ||
| 107 | dMinFitness = -1.0; | 139 | dMinFitness = -1.0; |
| 108 | dTotalFitness = 0.0; | 140 | dTotalFitness = 0.0; |
| 141 | mFitness.unlock(); | ||
| 142 | |||
| 109 | for( Population::iterator i = xPop.begin(); i; i++ ) | 143 | for( Population::iterator i = xPop.begin(); i; i++ ) |
| 110 | { | 144 | { |
| 111 | double dFitness; | ||
| 112 | if( hFitness.has( i.getKey() ) ) | 145 | if( hFitness.has( i.getKey() ) ) |
| 113 | { | 146 | { |
| 114 | dFitness = hFitness.get( i.getKey() ); | 147 | setFitness( i.getKey(), hFitness.get( i.getKey() ) ); |
| 115 | } | 148 | } |
| 116 | else | 149 | else |
| 117 | { | 150 | { |
| 118 | dFitness = (*pFunc)( *i ); | 151 | qWork.enqueue( *i ); |
| 119 | if( dFitness < 0.0 ) | ||
| 120 | dFitness = 0.0; | ||
| 121 | hFitness.insert( i.getKey(), dFitness ); | ||
| 122 | } | ||
| 123 | dTotalFitness += dFitness; | ||
| 124 | if( dMinFitness < 0.0 ) | ||
| 125 | { | ||
| 126 | dMinFitness = dMaxFitness = dFitness; | ||
| 127 | uMaxFitness = i.getKey(); | ||
| 128 | } | ||
| 129 | else if( dMinFitness > dFitness ) | ||
| 130 | { | ||
| 131 | dMinFitness = dFitness; | ||
| 132 | } | ||
| 133 | else if( dMaxFitness < dFitness ) | ||
| 134 | { | ||
| 135 | dMaxFitness = dFitness; | ||
| 136 | uMaxFitness = i.getKey(); | ||
| 137 | } | 152 | } |
| 138 | } | 153 | } |
| 154 | |||
| 155 | for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) | ||
| 156 | (*i)->start(); | ||
| 157 | |||
| 158 | for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) | ||
| 159 | (*i)->join(); | ||
| 160 | } | ||
| 161 | |||
| 162 | void Genetic::ExplicitSimulation::setFitness( Genetic::PhenotypeId id, | ||
| 163 | double dFitness ) | ||
| 164 | { | ||
| 165 | Bu::MutexLocker ml( mFitness ); | ||
| 166 | if( dFitness < 0.0 ) | ||
| 167 | dFitness = 0.0; | ||
| 168 | |||
| 169 | // sio << id << ": " << dFitness << sio.nl; | ||
| 170 | hFitness.insert( id, dFitness ); | ||
| 171 | |||
| 172 | dTotalFitness += dFitness; | ||
| 173 | if( dMinFitness < 0.0 ) | ||
| 174 | { | ||
| 175 | dMinFitness = dMaxFitness = dFitness; | ||
| 176 | uMaxFitness = id; | ||
| 177 | } | ||
| 178 | else if( dMinFitness > dFitness ) | ||
| 179 | { | ||
| 180 | dMinFitness = dFitness; | ||
| 181 | } | ||
| 182 | else if( dMaxFitness < dFitness ) | ||
| 183 | { | ||
| 184 | dMaxFitness = dFitness; | ||
| 185 | uMaxFitness = id; | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | Genetic::ExplicitSimulation::Processor::Processor( | ||
| 190 | Genetic::ExplicitSimulation &rSim, | ||
| 191 | Genetic::FitnessFunction *pFunc, | ||
| 192 | Genetic::ExplicitSimulation::WorkQueue &rqWork, | ||
| 193 | int iId ) : | ||
| 194 | rSim( rSim ), | ||
| 195 | pFunc( pFunc ), | ||
| 196 | rqWork( rqWork ), | ||
| 197 | iId( iId ) | ||
| 198 | { | ||
| 199 | } | ||
| 200 | |||
| 201 | Genetic::ExplicitSimulation::Processor::~Processor() | ||
| 202 | { | ||
| 203 | delete pFunc; | ||
| 204 | } | ||
| 205 | |||
| 206 | void Genetic::ExplicitSimulation::Processor::run() | ||
| 207 | { | ||
| 208 | bRunning = true; | ||
| 209 | while( bRunning && !rqWork.isEmpty() ) | ||
| 210 | { | ||
| 211 | Genetic::Phenotype *pPhen = rqWork.dequeue( 0, 250000 ); | ||
| 212 | if( pPhen == NULL ) | ||
| 213 | continue; | ||
| 214 | |||
| 215 | double dFitness = (*pFunc)( pPhen ); | ||
| 216 | rSim.setFitness( pPhen->getId(), dFitness ); | ||
| 217 | } | ||
| 139 | } | 218 | } |
| 219 | |||
diff --git a/src/explicitsimulation.h b/src/explicitsimulation.h index ebddd62..c2aeed9 100644 --- a/src/explicitsimulation.h +++ b/src/explicitsimulation.h | |||
| @@ -4,6 +4,10 @@ | |||
| 4 | #include "genetic/population.h" | 4 | #include "genetic/population.h" |
| 5 | #include "genetic/config.h" | 5 | #include "genetic/config.h" |
| 6 | 6 | ||
| 7 | #include <bu/thread.h> | ||
| 8 | #include <bu/mutex.h> | ||
| 9 | #include <bu/synchroqueue.h> | ||
| 10 | |||
| 7 | namespace Genetic | 11 | namespace Genetic |
| 8 | { | 12 | { |
| 9 | class Operator; | 13 | class Operator; |
| @@ -13,7 +17,8 @@ namespace Genetic | |||
| 13 | { | 17 | { |
| 14 | public: | 18 | public: |
| 15 | ExplicitSimulation( Operator *pOper, FitnessFunction *pFunc, | 19 | ExplicitSimulation( Operator *pOper, FitnessFunction *pFunc, |
| 16 | int iPopSize, float fKeep, float fRandom, bool bKeepBest=true ); | 20 | int iThreads, int iPopSize, float fKeep, float fRandom, |
| 21 | bool bKeepBest=true ); | ||
| 17 | virtual ~ExplicitSimulation(); | 22 | virtual ~ExplicitSimulation(); |
| 18 | 23 | ||
| 19 | void timestep(); | 24 | void timestep(); |
| @@ -25,11 +30,11 @@ namespace Genetic | |||
| 25 | 30 | ||
| 26 | protected: | 31 | protected: |
| 27 | void updateFitness(); | 32 | void updateFitness(); |
| 33 | void setFitness( Genetic::PhenotypeId, double dFitness ); | ||
| 28 | 34 | ||
| 29 | protected: | 35 | protected: |
| 30 | Population xPop; | 36 | Population xPop; |
| 31 | Operator *pOper; | 37 | Operator *pOper; |
| 32 | FitnessFunction *pFunc; | ||
| 33 | 38 | ||
| 34 | private: | 39 | private: |
| 35 | int iPopSize; | 40 | int iPopSize; |
| @@ -42,6 +47,32 @@ namespace Genetic | |||
| 42 | double dMaxFitness; | 47 | double dMaxFitness; |
| 43 | double dTotalFitness; | 48 | double dTotalFitness; |
| 44 | PhenotypeId uMaxFitness; | 49 | PhenotypeId uMaxFitness; |
| 50 | |||
| 51 | Bu::Mutex mFitness; | ||
| 52 | typedef Bu::SynchroQueue<Phenotype *> WorkQueue; | ||
| 53 | WorkQueue qWork; | ||
| 54 | |||
| 55 | class Processor : public Bu::Thread | ||
| 56 | { | ||
| 57 | public: | ||
| 58 | Processor( ExplicitSimulation &rSim, FitnessFunction *pFunc, | ||
| 59 | WorkQueue &rqWork, int iId ); | ||
| 60 | virtual ~Processor(); | ||
| 61 | |||
| 62 | void setRunning( bool b ) { bRunning = b; } | ||
| 63 | |||
| 64 | protected: | ||
| 65 | virtual void run(); | ||
| 66 | |||
| 67 | ExplicitSimulation &rSim; | ||
| 68 | FitnessFunction *pFunc; | ||
| 69 | WorkQueue &rqWork; | ||
| 70 | int iId; | ||
| 71 | bool bRunning; | ||
| 72 | }; | ||
| 73 | |||
| 74 | typedef Bu::List<Processor *> ProcessorList; | ||
| 75 | ProcessorList lProcessor; | ||
| 45 | }; | 76 | }; |
| 46 | }; | 77 | }; |
| 47 | 78 | ||
diff --git a/src/fitnessfunction.h b/src/fitnessfunction.h index c41f733..0f852fa 100644 --- a/src/fitnessfunction.h +++ b/src/fitnessfunction.h | |||
| @@ -12,6 +12,7 @@ namespace Genetic | |||
| 12 | virtual ~FitnessFunction(); | 12 | virtual ~FitnessFunction(); |
| 13 | 13 | ||
| 14 | virtual double operator()( Phenotype *pTest )=0; | 14 | virtual double operator()( Phenotype *pTest )=0; |
| 15 | virtual FitnessFunction *clone() const=0; | ||
| 15 | }; | 16 | }; |
| 16 | }; | 17 | }; |
| 17 | 18 | ||
diff --git a/src/tests/maxima/fitnessfunctioneq.cpp b/src/tests/maxima/fitnessfunctioneq.cpp index 5694507..c64e87a 100644 --- a/src/tests/maxima/fitnessfunctioneq.cpp +++ b/src/tests/maxima/fitnessfunctioneq.cpp | |||
| @@ -23,3 +23,8 @@ double FitnessFunctionEq::operator()( Genetic::Phenotype *pTest ) | |||
| 23 | return -1.8*(x*x*x*x) + 0.86*(x*x*x) + 4.0*(x*x); | 23 | return -1.8*(x*x*x*x) + 0.86*(x*x*x) + 4.0*(x*x); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | Genetic::FitnessFunction *FitnessFunctionEq::clone() const | ||
| 27 | { | ||
| 28 | return new FitnessFunctionEq(); | ||
| 29 | } | ||
| 30 | |||
diff --git a/src/tests/maxima/fitnessfunctioneq.h b/src/tests/maxima/fitnessfunctioneq.h index 7139532..d1a64c5 100644 --- a/src/tests/maxima/fitnessfunctioneq.h +++ b/src/tests/maxima/fitnessfunctioneq.h | |||
| @@ -10,6 +10,7 @@ public: | |||
| 10 | virtual ~FitnessFunctionEq(); | 10 | virtual ~FitnessFunctionEq(); |
| 11 | 11 | ||
| 12 | virtual double operator()( Genetic::Phenotype *pTest ); | 12 | virtual double operator()( Genetic::Phenotype *pTest ); |
| 13 | virtual Genetic::FitnessFunction *clone() const; | ||
| 13 | }; | 14 | }; |
| 14 | 15 | ||
| 15 | #endif | 16 | #endif |
diff --git a/src/tests/maxima/main.cpp b/src/tests/maxima/main.cpp index ec02a41..db11f66 100644 --- a/src/tests/maxima/main.cpp +++ b/src/tests/maxima/main.cpp | |||
| @@ -23,6 +23,7 @@ int main( int argc, char *argv[] ) | |||
| 23 | 0.05 | 23 | 0.05 |
| 24 | ), | 24 | ), |
| 25 | new FitnessFunctionEq(), | 25 | new FitnessFunctionEq(), |
| 26 | 4, | ||
| 26 | 1000, | 27 | 1000, |
| 27 | .1, .1 | 28 | .1, .1 |
| 28 | ); | 29 | ); |
