summaryrefslogtreecommitdiff
path: root/src/explicitsimulation.cpp
diff options
context:
space:
mode:
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