00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __BB2004Evo_h__
00013 #define __BB2004Evo_h__
00014
00015 #include <stdlib.h>
00016
00017
00018
00019
00020
00021 class BBIndividual
00022 {
00023 public:
00024
00025
00026
00027
00028
00029 virtual void init(const BBIndividual& initial) = 0;
00030
00031
00032
00033
00034
00035
00036
00037 virtual void interpolate(const BBIndividual& other) = 0;
00038
00039
00040
00041
00042
00043
00044 virtual void extrapolate(const BBIndividual& other) = 0;
00045
00046
00047
00048
00049
00050 virtual void mutate() = 0;
00051
00052
00053
00054
00055
00056
00057 virtual double getFitness() const = 0;
00058 };
00059
00060
00061
00062
00063 class Statistics
00064 {
00065 private:
00066 int size;
00067 int* stats;
00068
00069
00070
00071
00072
00073
00074
00075
00076 static int compare(const int* i1, const int* i2)
00077 {
00078 return *i1 > *i2 ? -1 : *i1 < *i2;
00079 }
00080
00081 public:
00082
00083
00084
00085
00086 Statistics(int size)
00087 {
00088 this->size = size;
00089 stats = new int[size];
00090 reset();
00091 }
00092
00093
00094
00095
00096 ~Statistics() {delete [] stats;}
00097
00098
00099
00100
00101 void reset()
00102 {
00103 for(int i = 0; i < size; ++i)
00104 stats[i] = 0;
00105 }
00106
00107
00108
00109
00110
00111 void add(int index) {++stats[index];}
00112
00113
00114
00115
00116
00117
00118
00119 int analyze()
00120 {
00121 int dest = 0,
00122 src;
00123 for(src = 0; src < size; ++src)
00124 if(stats[src])
00125 stats[dest++] = stats[src];
00126 qsort(stats, dest, sizeof(int), (int (*)(const void*, const void*)) compare);
00127 return dest;
00128 }
00129
00130
00131
00132
00133
00134
00135 int operator[](int index) const {return stats[index];}
00136 };
00137
00138
00139
00140
00141
00142
00143 template<class T> class BBPopulation
00144 {
00145 private:
00146 Statistics statistics;
00147 T* current,
00148 * old;
00149 int size;
00150 double* fitness;
00151 double* fitnessSum;
00152 double overallFitness;
00153
00154
00155
00156
00157
00158 static double random() {return rand() / (double(RAND_MAX) + 1);}
00159
00160
00161
00162
00163
00164
00165
00166 const T& drawIndividual()
00167 {
00168 double randomValue = random() * overallFitness;
00169 int low = 0,
00170 up = size;
00171 while(low != up - 1)
00172 {
00173 int middle = (low + up) / 2;
00174 if(randomValue < fitnessSum[middle])
00175 up = middle;
00176 else
00177 low = middle;
00178 }
00179 statistics.add(low);
00180 return old[low];
00181 }
00182
00183
00184
00185
00186
00187 void updateFitness()
00188 {
00189 overallFitness = 0;
00190 for(int i = 0; i < size; ++i)
00191 {
00192 fitnessSum[i] = overallFitness;
00193 fitness[i] = current[i].getFitness();
00194 overallFitness += fitness[i];
00195 }
00196 }
00197
00198
00199
00200
00201 void mutate()
00202 {
00203 int i;
00204 for(i = 0; i < size && statistics[i] <= size; ++i)
00205 ;
00206 if(i < size)
00207 for(i = 0; i < size; i += 2)
00208 current[i].mutate();
00209 }
00210
00211 public:
00212
00213
00214
00215
00216
00217 BBPopulation(int size, const BBIndividual& initial)
00218 : statistics(size)
00219 {
00220 this->size = size;
00221 current = new T[size];
00222 old = new T[size];
00223 fitness = new double[size];
00224 fitnessSum = new double[size];
00225 for(int i = 0; i < size; ++i)
00226 current[i].init(initial);
00227 }
00228
00229
00230
00231
00232 ~BBPopulation()
00233 {
00234 delete [] current;
00235 delete [] old;
00236 delete [] fitness;
00237 delete [] fitnessSum;
00238 }
00239
00240
00241
00242
00243
00244 int getSize() const {return size;}
00245
00246
00247
00248
00249
00250
00251 T& operator[](int index) {return current[index];}
00252
00253
00254
00255
00256
00257
00258 const T& operator[](int index) const {return current[index];}
00259
00260
00261
00262
00263
00264 void interpolate()
00265 {
00266 updateFitness();
00267
00268
00269 T* temp = old;
00270 old = current;
00271 current = temp;
00272
00273 statistics.reset();
00274 for(int i = 0; i < size; ++i)
00275 {
00276 current[i] = drawIndividual();
00277 current[i].interpolate(drawIndividual());
00278 }
00279 mutate();
00280 }
00281
00282 void extrapolate()
00283 {
00284 updateFitness();
00285
00286
00287 T* temp = old;
00288 old = current;
00289 current = temp;
00290
00291 statistics.reset();
00292 for(int i = 0; i < size; ++i)
00293 {
00294 current[i] = drawIndividual();
00295 current[i].extrapolate(drawIndividual());
00296 }
00297 mutate();
00298 }
00299
00300 const BBIndividual& getFittest()
00301 {
00302 updateFitness();
00303
00304 int fittest = 0;
00305 for(int i = 1; i < size; ++i)
00306 if(fitness[fittest] < fitness[i])
00307 fittest = i;
00308 return current[fittest];
00309 }
00310
00311 Statistics& getStatistics() {return statistics;}
00312 };
00313
00314 #endif // __BB2004Evo_h_
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338