00001
00021
00022
00023
00024
00025
00026 #ifndef __GAL_POPULATION_H
00027 #define __GAL_POPULATION_H
00028
00029 #include <iostream>
00030 #include <fstream>
00031 #include <vector>
00032 #include <string>
00033 #include <map>
00034 #include <algorithm>
00035 #include "Util.h"
00036 #include "Chromosome.h"
00037 #include "Problem.h"
00038
00039 #define DOUBLE_MAX 1.7E+308
00040 namespace gal {
00041
00054 template <class T> class Population {
00055 private:
00056 Problem<T>* _problem;
00057 std::vector<Chromosome<T>* > _members;
00058 std::vector<double> _objvalues;
00059 std::vector<double> _fitnesses;
00060 double _totalFitness;
00061 std::vector<int> _currentElite;
00062 int _nrMem;
00063 int _nrElite;
00064 double _probMutate;
00065 double _probCrossover;
00066 int _objmaxindex;
00067 int _objminindex;
00068 double _objavg;
00069 double _prevmax;
00070 double _overallmax;
00071 double _nrequalmax;
00072
00073
00074
00075 public:
00082 Population(Problem<T>* problem) : _problem(problem), _members(),
00083 _nrElite(0), _probMutate(0.0), _probCrossover(0.0) {}
00084
00094 Population(Problem<T>* problem,
00095 int size, int chromoLength) : _problem(problem), _members(),
00096 _nrElite(0), _probMutate(0.0), _probCrossover(0.0)
00097 {
00098 initialise(size, chromoLength);
00099 }
00100
00104 ~Population()
00105 {
00106 typename std::vector<Chromosome<T>* >::iterator it;
00107
00108 for (it = _members.begin(); it != _members.end(); ++it) {
00109 _problem->deleteChromosome(*it);
00110 }
00111 }
00112
00113 public:
00119 void addMember(Chromosome<T>* g)
00120 {
00121 _members[_nrMem] = g;
00122 _objvalues[_nrMem] = 0.0;
00123 _fitnesses[_nrMem] = 0.0;
00124 _nrMem++;
00125 }
00126
00130 int const size()
00131 {
00132 return _nrMem;
00133
00134
00135 }
00136
00143 void initialise(int size, int chromoLength)
00144 {
00145 Chromosome<T>* tmpChr;
00146
00147 _members.clear();
00148 _members.resize(size);
00149 _objvalues.resize(size);
00150 _fitnesses.resize(size);
00151 _nrMem = 0;
00152 for (int i = 0; i < size; ++i) {
00153 tmpChr = _problem->constructChromosome(chromoLength);
00154 addMember(tmpChr);
00155 }
00156 _prevmax=-1E+100;
00157 _overallmax=-1E+100;
00158 _nrequalmax=0;
00159 _objmaxindex=0;
00160 _objvalues[_objmaxindex] = _overallmax;
00161 evaluateFitness();
00162
00163 }
00164
00169 void setEliteSize(int nrElite)
00170 {
00171 _nrElite = nrElite > 0 ? nrElite : 0;
00172 }
00173
00185 void setProbabilities(double probMutate, double probCrossover)
00186 {
00187 _probMutate = probMutate;
00188 _probCrossover = probCrossover;
00189 }
00190
00191 public:
00199 void evaluateFitness()
00200 {
00201
00202
00203 double a, b;
00204 a = 1.0;
00205 b = 10.0;
00206
00207
00208
00209
00210
00211
00212
00213
00214 markElite();
00215 }
00216
00222 void markElite()
00223 {
00224 int i, imax;
00225 double maxfit;
00226 std::map<int, double> fitnessbackup;
00227 std::map<int, double>::iterator it;
00228
00229
00230
00231
00232
00233
00234
00235
00236 }
00237
00238 public:
00244 void mutate()
00245 {
00246 typename std::vector<Chromosome<T>* >::iterator it;
00247
00248
00249
00250
00251 }
00252
00260 int selectByRoulette()
00261 {
00262
00263
00264
00265
00266
00267
00268 return _members.front();
00269 }
00270
00278 void selectAndReproduce()
00279 {
00280 typename std::vector<Chromosome<T>* >::iterator it;
00281 int i, isel, nrParents, countElite, countNext;
00282 double tresh, sumFitness;
00283 std::vector<Chromosome<T>* > nextgen;
00284 Chromosome<T>* sel;
00285 Chromosome<T>* child1;
00286 Chromosome<T>* child2;
00287 Chromosome<T>** parents = new Chromosome<T>*[2];
00288 std::vector<int>::iterator eliteAt, tmpAt;
00289
00290
00291
00292
00293
00294
00295
00296 nextgen.resize(size());
00297 countNext = 0;
00298 countElite = 0;
00299
00300 while (countNext < size()) {
00301 nrParents = 0;
00302
00303
00304 while (nrParents < 2 && countNext < size()) {
00305
00306
00307
00308
00309
00310
00311 }
00312
00313
00314 if (nrParents == 2 && countNext < size()-1) {
00315
00316
00317
00318
00319
00320
00321
00322
00323 } else {
00324 #ifdef __GAL_DEBUG
00325 std::cout << "Next generation is full, discard children." << std::endl;
00326 #endif
00327 }
00328 }
00329 delete [] parents;
00330
00331
00332
00333
00334
00335
00336 _members = nextgen;
00337 }
00338
00345 void nextGeneration()
00346 {
00347
00348
00349
00350
00351
00352
00353 mutate();
00354
00355 evaluateFitness();
00356 }
00357
00358 public:
00359
00360 #define PRINTINTERP 1
00361 #define PRINTBITSTRING 2
00362 #define PRINTVALUE 4
00363 #define PRINTOBJECTIVE 8
00364 #define PRINTFITNESS 16
00365
00366 #define PRINTALL 1
00367 #define PRINTBEST 2
00368 #define PRINTWORST 4
00369 #define PRINTAVG 8
00370 #define ONLYIFBETTER 16
00371
00388 void const print(int generationNr, int printbits, int printmode, std::ostream& outstr)
00389 {
00390 typename std::vector<Chromosome<T>* >::iterator it;
00391 int i = 0;
00392 int index;
00393
00394 if (printmode & ONLYIFBETTER) {
00395 if(_overallmax >= _objvalues[_objmaxindex]) {
00396 return;
00397 }
00398 }
00399
00400 outstr.precision(12);
00401 if(printmode&PRINTALL) {
00402 for (it = _members.begin(); it != _members.end(); ++it)
00403 {
00404 if(generationNr>=0)
00405 outstr << generationNr+1 << "\t";
00406 if(printbits & PRINTINTERP)
00407 outstr << (*it)->getInterpretedBitstringText() << "\t";
00408 if(printbits & PRINTBITSTRING)
00409 {
00410 outstr << (*it)->getBitstringText() << "\t";
00411
00412
00413 }
00414 if(printbits & PRINTVALUE)
00415 outstr <<(*it)->getValueText() << "\t";
00416 if (printbits & PRINTOBJECTIVE)
00417 outstr << _objvalues[i] << "\t";
00418 if (printbits & PRINTFITNESS)
00419 outstr << "Fit: " << _fitnesses[i] << "\t";
00420 outstr << std::endl;
00421 i++;
00422 }
00423 }
00424 else if(printmode&PRINTAVG)
00425 {
00426 if(generationNr>=0)
00427 outstr << generationNr+1 << "\t";
00428 if(printbits & PRINTOBJECTIVE)
00429 outstr << _objavg << std::endl;
00430 if(printbits & ( PRINTINTERP | PRINTBITSTRING | PRINTVALUE | PRINTFITNESS))
00431 outstr << "Options make no sense voor print-average" << std::endl;
00432
00433 }
00434 else
00435 {
00436 if(printmode & PRINTWORST)
00437 {
00438 outstr << "TODO ";
00439 index=_objmaxindex;
00440 }
00441 else if(printmode & PRINTBEST)
00442 index=_objmaxindex;
00443
00444 it = _members.begin();
00445 it += index;
00446
00447 if(generationNr>=0)
00448 outstr << generationNr+1 << "\t";
00449 if (printbits & PRINTOBJECTIVE)
00450 outstr << _objvalues[index] << "\t";
00451 if(printbits & PRINTBITSTRING)
00452 outstr << (*it)->getBitstringText() << "\t";
00453 outstr << std::endl;
00454
00455 }
00456 }
00457
00466 int testConvergence(int nrequal)
00467 {
00468 double objmax = _objvalues[_objmaxindex];
00469
00470 if(objmax==_prevmax)
00471 _nrequalmax++;
00472 else
00473 _nrequalmax=0;
00474
00475 if(_nrequalmax==nrequal)
00476 return 1;
00477 else
00478 return 0;
00479
00480 }
00481
00489 void writePopulation(std::ostream& outstr)
00490 {
00491 typename std::vector<Chromosome<T>* >::iterator it;
00492 int i;
00493
00494 outstr << "# Bitstring\tElite?\tValue\tObj.value" << std::endl;
00495
00496 i = 0;
00497 for (it = _members.begin(); it != _members.end(); ++it)
00498 {
00499 outstr << (*it)->getBitstringText();
00500 outstr << "\t";
00501 if ((*it)->isElite())
00502 outstr << "*";
00503 outstr << "\t" << (*it)->getValueText();
00504 outstr << "\t" << _objvalues[i];
00505 outstr << std::endl;
00506 i++;
00507 }
00508 }
00509
00510
00511
00512
00513
00524 void readPopulation(std::istream& instr)
00525 {
00526 int chromoLength;
00527 Chromosome<T>* tmpChr;
00528
00529 if (size() == 0 || (chromoLength = _members[0]->length()) == 0) {
00530 std::cerr << "** Unexpected population size or bitlength! Is Population unitialised?" << std::endl;
00531 return;
00532 }
00533
00534 char chromoString[5*chromoLength];
00535 char c;
00536
00537 int err = 0;
00538 int i;
00539
00540
00541 instr.ignore (1000000, '\n');
00542 if (instr.peek() == '\r') instr.ignore (1);
00543
00544 i = 0;
00545 while (i < size() && !instr.eof()) {
00546 instr.getline(chromoString, 1000000, '\t');
00547 std::cout << "just read: \"" << chromoString << "\"" << std::endl;
00548 tmpChr = _problem->copyChromosome(_members[i]);
00549 tmpChr->setBits(chromoString);
00550
00551
00552 c = instr.peek();
00553 if (c == '*') {
00554 tmpChr->setElite(true);
00555 } else if (c == '\t') {
00556 tmpChr->setElite(false);
00557 } else {
00558 std::cerr << "** Unexpected character '" << c << "' (" << (int)c << ") at line " << (i+2) << ", pos. " << (chromoLength+1) << "." << std::endl;
00559 std::cerr << " Are bitstrings in file longer than current bitstrings?" << std::endl;
00560 err = 1;
00561 break;
00562 }
00563
00564 delete _members[i];
00565 _members[i] = tmpChr;
00566
00567 instr.ignore (1000000, '\n');
00568 if (instr.peek() == '\r') instr.ignore (1);
00569
00570 i++;
00571 }
00572
00573 if (i != size()) {
00574 std::cerr << "** File was smaller than population." << std::endl;
00575 err = 1;
00576 }
00577
00578 if (!instr.eof()) {
00579 std::cerr << "** File was larger than population." << std::endl;
00580 }
00581
00582 if (err) {
00583 std::cerr << "** Exiting." << std::endl;
00584 exit(1);
00585
00586
00587
00588 }
00589 evaluateFitness();
00590 }
00591
00592 };
00593 }
00594 #endif