diff options
Diffstat (limited to 'src/explicitsimulation.cpp')
-rw-r--r-- | src/explicitsimulation.cpp | 130 |
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 | ||
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 | |||