summaryrefslogtreecommitdiff
path: root/src/explicitsimulation.cpp
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2012-07-17 09:11:40 -0600
committerMike Buland <mike@xagasoft.com>2012-07-17 09:11:40 -0600
commita2679e3bc2f407fae6b97908aeebb215c6678ebc (patch)
treeac220ef865dc38b6b4a10a03e5d48aad261cddd3 /src/explicitsimulation.cpp
parenta48556c1c5c01892cf493cd3eb4ff969a2f548fd (diff)
downloadlibgenetic-a2679e3bc2f407fae6b97908aeebb215c6678ebc.tar.gz
libgenetic-a2679e3bc2f407fae6b97908aeebb215c6678ebc.tar.bz2
libgenetic-a2679e3bc2f407fae6b97908aeebb215c6678ebc.tar.xz
libgenetic-a2679e3bc2f407fae6b97908aeebb215c6678ebc.zip
It all works multi-threaded.
It restarts the threads every generation. Maybe not the worst thing every, but it seems like it would be better to stay in the thread and notify the main thread that they're done with that iteration.
Diffstat (limited to 'src/explicitsimulation.cpp')
-rw-r--r--src/explicitsimulation.cpp130
1 files changed, 105 insertions, 25 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
8using namespace Bu; 12using namespace Bu;
9 13
10Genetic::ExplicitSimulation::ExplicitSimulation( Genetic::Operator *pOper, 14Genetic::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
28Genetic::ExplicitSimulation::~ExplicitSimulation() 42Genetic::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
34void Genetic::ExplicitSimulation::timestep() 55void 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
87Genetic::PhenotypeId Genetic::ExplicitSimulation::selectWeighted() 114Genetic::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
105void Genetic::ExplicitSimulation::updateFitness() 136void 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
162void 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
189Genetic::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
201Genetic::ExplicitSimulation::Processor::~Processor()
202{
203 delete pFunc;
204}
205
206void 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