summaryrefslogtreecommitdiff
path: root/src/explicitsimulation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/explicitsimulation.cpp')
-rw-r--r--src/explicitsimulation.cpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/explicitsimulation.cpp b/src/explicitsimulation.cpp
new file mode 100644
index 0000000..281e7e5
--- /dev/null
+++ b/src/explicitsimulation.cpp
@@ -0,0 +1,139 @@
1#include "genetic/explicitsimulation.h"
2#include "genetic/operator.h"
3#include "genetic/fitnessfunction.h"
4
5#include <bu/random.h>
6#include <bu/sio.h>
7
8using namespace Bu;
9
10Genetic::ExplicitSimulation::ExplicitSimulation( Genetic::Operator *pOper,
11 Genetic::FitnessFunction *pFunc, int iPopSize, float fKeep,
12 float fRandom, bool bKeepBest ) :
13 pOper( pOper ),
14 pFunc( pFunc ),
15 iPopSize( iPopSize ),
16 fKeep( fKeep ),
17 fRandom( fRandom ),
18 bKeepBest( bKeepBest )
19{
20 for( int j = 0; j < iPopSize; j++ )
21 {
22 xPop.addPhenotype( pOper->random() );
23 }
24
25 updateFitness();
26}
27
28Genetic::ExplicitSimulation::~ExplicitSimulation()
29{
30 delete pOper;
31 delete pFunc;
32}
33
34void Genetic::ExplicitSimulation::timestep()
35{
36 PhenotypeList lNew;
37
38 int iChildren = iPopSize*(1.0-fKeep-fRandom);
39
40 // Create children
41 for( int j = 0; j < iChildren; j++ )
42 {
43 PhenotypeList lParents;
44 for( int k = 0; k < pOper->parentCount(); k++ )
45 lParents.append( xPop.getPhenotype( selectWeighted() ) );
46 lNew.append( pOper->mate( lParents ) );
47 }
48
49 // Select phenotypes for keeping
50 int iKeep = iPopSize*fKeep;
51 FitnessHash hTempFitness;
52 for( int j = 0; j < iKeep; j++ )
53 {
54 Genetic::PhenotypeId id = selectWeighted();
55 lNew.append( xPop.takePhenotype( id ) );
56 hTempFitness.insert( id, hFitness.get( id ) );
57 hFitness.erase( id );
58 dTotalFitness -= hTempFitness.get( id );
59 }
60
61 if( bKeepBest && hFitness.has( uMaxFitness ) )
62 {
63 lNew.append( xPop.takePhenotype( uMaxFitness ) );
64 hTempFitness.insert( uMaxFitness, hFitness.get( uMaxFitness ) );
65 hFitness.erase( uMaxFitness );
66 dTotalFitness -= hTempFitness.get( uMaxFitness );
67 }
68
69 // Fill in the remainder with random phenotypes
70 while( lNew.getSize() < iPopSize )
71 {
72 lNew.append( pOper->random() );
73 }
74
75 // Refill the population
76 hFitness = hTempFitness;
77 xPop.clear();
78 xPop.timestep();
79 for( PhenotypeList::iterator i = lNew.begin(); i; i++ )
80 {
81 xPop.addPhenotype( *i );
82 }
83
84 updateFitness();
85}
86
87Genetic::PhenotypeId Genetic::ExplicitSimulation::selectWeighted()
88{
89 double dSel = Bu::Random::randNorm()*dTotalFitness;
90 double dRun = 0.0;
91
92 for( FitnessHash::iterator i = hFitness.begin(); i; i++ )
93 {
94 dRun += *i;
95 if( dSel < dRun )
96 return i.getKey();
97 }
98
99 sio << "Genetic::ExplicitSimulation::selectWeighted() - failed, picked max"
100 << sio.nl;
101
102 return uMaxFitness;
103}
104
105void Genetic::ExplicitSimulation::updateFitness()
106{
107 dMinFitness = -1.0;
108 dTotalFitness = 0.0;
109 for( Population::iterator i = xPop.begin(); i; i++ )
110 {
111 double dFitness;
112 if( hFitness.has( i.getKey() ) )
113 {
114 dFitness = hFitness.get( i.getKey() );
115 }
116 else
117 {
118 dFitness = (*pFunc)( *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 }
138 }
139}