00001 #ifndef EVOPOPULATION_H
00002 #define EVOPOPULATION_H
00003
00004 #include<iostream>
00005 #include<fstream>
00006 #include<sstream>
00007 #include<cstdlib>
00008 #include<ctime>
00009 #include<cstddef>
00010 #include<string>
00011 #include<vector>
00012 #include<list>
00013 #include<iterator>
00014 #include<math.h>
00015 #include<fcntl.h>
00016
00017 using namespace std;
00018
00019 template<class T>
00020 class EvoRandomizer;
00021
00024 class EvoTest
00025 {
00026 public:
00027 EvoTest(){}
00028 EvoTest(int i,char*f,int d) : size(i), filename(f), id(d){}
00029 virtual ~EvoTest(){}
00030 virtual double run(double* ix,int a) = 0;
00031 char* filename;
00032 int size;
00033 int id;
00034 };
00035
00039 class Test6 : public EvoTest
00040 {
00041 public:
00042 Test6(int i,char*f,int d) : EvoTest(i,f,d){}
00043 double run(double* x,int n){
00044 return (-1)*(100*pow((x[1]-x[0]*x[0]),2) + pow((1 - x[0]),2) + 90*pow((x[3]-x[2]*x[2]),2) + pow((1 - x[2]),2) +
00045 10.1*pow((x[1] -1),2) + pow((x[3]-1),2));
00046 }
00047 };
00048
00053 class DeJongF1 : public EvoTest
00054 {
00055 public:
00056 DeJongF1(int i,char*f,int d) : EvoTest(i,f,d){}
00057 double run(double* x,int n = 3){
00058 double sum=0;
00059
00060 for(int i=0;i<n;i++){
00061 sum += x[i]*x[i];
00062 }
00063 return (-1)*sum;
00064 }
00065 };
00066
00071 class DeJongF2 : public EvoTest
00072 {
00073 public:
00074 DeJongF2(int i,char*f,int d) : EvoTest(i,f,d){}
00075 double run(double* x,int n = 2){
00076 return (-100)*(((x[0]*x[0]) - x[1])*((x[0]*x[0]) - x[1]) + ((1-x[0])*(1-x[0])));
00077 }
00078 };
00079
00084 class DeJongF3 : public EvoTest
00085 {
00086 public:
00087 DeJongF3(int i,char*f,int d) : EvoTest(i,f,d){}
00088 double run(double* x,int n = 5){
00089 double sum=0;
00090 for(int i=0;i<n;i++)
00091 sum += int(x[i]);
00092 return (-1)*sum;
00093 }
00094 };
00095
00100 class DeJongF4 : public EvoTest
00101 {
00102 public:
00103 DeJongF4(int i,char*f,int d) : EvoTest(i,f,d){}
00104 double run(double* x,int n = 30){
00105 double sum=0;
00106 for(int i=0;i<n;i++)
00107 sum += i*x[i]*x[i]*x[i]*x[i];
00108 return (-1)*sum;
00109 }
00110 };
00111
00116 class EvoGen
00117 {
00118 public:
00120 EvoGen(double v,double l,double u){
00121 value = v;
00122 lbound = l;
00123 ubound = u;
00124 }
00128 EvoGen(const EvoGen& gen){
00129 value = gen.value;
00130 lbound = gen.lbound;
00131 ubound = gen.ubound;
00132 }
00133
00134 ~EvoGen(){}
00135
00136 friend ostream& operator<<(ostream& os, const EvoGen& eg){
00137 return os <<"# "<< (double)(eg.value)<< " " <<(double)(eg.lbound) << " " << (double)(eg.ubound); }
00138
00142 double value;
00146 double ubound;
00150 double lbound;
00151 };
00152
00157 template<typename T>
00158 class EvoGenotype : public std::vector<T>
00159 {
00160 public:
00165 EvoGenotype(unsigned int size, const char* filename){
00166
00167 fitness = 0;
00168 cfitness = 0;
00169 rfitness = 0;
00170 generation = 0;
00171
00172 double lb, ub = 0;
00173 reserve(size);
00174 ifstream in(filename);
00175
00176 string line;
00177
00178 while(getline(in,line)){
00179 istringstream s(line);
00180 s >> lb >> ub ;
00181 push_back(T(0,lb,ub));
00182 }
00183
00184 }
00185
00186 EvoGenotype() {
00187 fitness = 0;
00188 cfitness = 0;
00189 rfitness = 0;
00190 generation = 0;
00191 }
00192
00193 ~EvoGenotype(){}
00194
00195
00196 friend ostream& operator<<(ostream& os, EvoGenotype<T>& eg){
00197 typename EvoGenotype<T>::iterator it = eg.begin();
00198 while(it != eg.end())
00199 os << *it++ << endl;
00200 return os;
00201 }
00205 void show(){
00206 typename EvoGenotype<T>::iterator it = begin();
00207 while(it != end())
00208 cout << *it++ << endl;
00209 }
00210
00215 void addGen(double v,double lb, double ub){
00216
00217 push_back(T(v,lb,ub));
00218 }
00219
00223 double fitness;
00227 double cfitness;
00231 double rfitness;
00235 unsigned int generation;
00236
00237 };
00238
00243 template<class T>
00244 class EvoPopulation : public std::list<T>
00245 {
00246 public:
00260 EvoPopulation(){
00261 it_best = begin();
00262 it_worst = end();
00263 worst = 10000;
00264 best = 0;
00265 randmachine = new EvoRandomizer<T>;
00266 }
00267 ~EvoPopulation(){}
00268
00269 void seed(){
00270 typename EvoPopulation<T>::iterator it = begin();
00271 typename T::iterator it_genotype;
00272 while(it != end()){
00273 it_genotype = (*it).begin();
00274 while(it_genotype != (*it).end() ){
00275 (*it_genotype).value = randmachine->random((*it_genotype).lbound, (*it_genotype).ubound);
00276 it_genotype++;
00277 }
00278 it++;
00279 }
00280 }
00281
00282 friend ostream& operator<<(ostream& os, EvoPopulation<T>& ep){
00283 typename EvoPopulation<T>::iterator it = ep.begin();
00284 while(it != ep.end())
00285 os << "<GENOTYPE>" << endl << *it++ << "</GENOTYPE>" << endl ;
00286 return os;
00287 }
00288
00289 void show(){
00290 int i =0;
00291 typename EvoPopulation<T>::iterator it = begin();
00292 while(it != end()){
00293 cout << i++ << ":" << (*it).fitness << " " << (*it).rfitness << " " << (*it).cfitness << " " <<(*it).generation <<endl;
00294 (*it++).show();
00295 }
00296 cout << "Najlepszy :"<< best << endl << "Najgorszy :" << worst << endl;
00297 }
00298
00299 double best;
00300 double worst;
00301
00302 typename EvoPopulation<T>::iterator it_best;
00303 typename EvoPopulation<T>::iterator it_worst;
00304 private:
00305 EvoRandomizer<T>* randmachine;
00306 };
00307
00308
00309
00310
00311
00312
00313
00314 template<class T>
00315 class EvoRandomizer
00316 {
00317 public:
00318 int int_rand(int low, int height){ return ((int)(std::rand()%(height-low)) + low);}
00319
00320 double random(double ubound, double lbound){
00321
00322 return (((double)(std::rand()%1000)/1000.0)*(ubound-lbound)+lbound);
00323 }
00324 };
00325
00326 template<> class EvoRandomizer< EvoGenotype<EvoGen*> >
00327 {
00328 public:
00329 int int_rand(int low, int height){ return ((int)(std::rand()%(height-low)) + low);}
00330
00331 double random(double ubound, double lbound){
00332 return (((double)(std::rand()%1000)/1000.0)*(ubound-lbound)+lbound);
00333 }
00334 };
00335
00336 template<> class EvoRandomizer< EvoGenotype<EvoGen> >
00337 {
00338 public:
00339 int int_rand(int low, int height){ return ((int)(std::rand()%(height-low)) + low);}
00340
00341 double random(double lbound, double ubound){
00342 return (((double)(rand()%1000)/1000.0)*(ubound-lbound)+lbound);
00343 }
00344 };
00345
00346 template<typename type>
00347 class EvoProcess
00348 {
00349 public:
00350 EvoProcess(){}
00351 virtual ~EvoProcess(){}
00352 virtual void command(){ cout << "Base" <<endl; }
00353 virtual void command(type&){ cout << "Base" <<endl; }
00354 virtual void command(type&,type&){ cout << "Base" <<endl; }
00355 virtual void command(EvoPopulation<type>&){ cout << "Base" << endl; }
00356 virtual void command(EvoPopulation<type>&,EvoPopulation<type>&){ cout << "Base" << endl; }
00357 };
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00373 template<typename type>
00374 class EvoCodec
00375 {
00376 public:
00377 EvoCodec() : size(0){}
00378 ~EvoCodec(){}
00379
00380 unsigned int size;
00381 double* valueArray;
00382
00383 double* decode(type& genom){
00384 size = genom.size();
00385 valueArray = new double[size];
00386 for(unsigned int i=0;i<size;i++)
00387 valueArray[i] = genom[i].value;
00388 return valueArray;
00389 }
00390 };
00391
00395 template<typename type>
00396 class EvoEvaluator : public EvoProcess<type>
00397 {
00398 public:
00399 EvoEvaluator(EvoTest* t) : test(t), decoder(new EvoCodec<type>) {}
00400 ~EvoEvaluator(){}
00401
00402 virtual void command(EvoPopulation<type>& pop){
00403 pop.worst = 100000;
00404 pop.best = -100000;
00405 typename EvoPopulation<type>::iterator it = pop.begin();
00406 while(it != pop.end()){
00407 (*it).fitness = test->run(decoder->decode(*it),(*it).size());
00408
00409 if(pop.worst > (*it).fitness){
00410 pop.worst = (*it).fitness;
00411 pop.it_worst = it;
00412 }
00413 if(pop.best < (*it).fitness){
00414 pop.best = (*it).fitness;
00415 pop.it_best = it;
00416 }
00417 it++;
00418 }
00419 }
00420
00421 private:
00422 EvoTest* test;
00423 EvoCodec<type>* decoder;
00424 };
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00462 template<class T>
00463 class EvoProcessList;
00464
00465 template<typename type>
00466 class EvoSelector : public EvoProcess<type>
00467 {
00468
00469 public:
00470 EvoSelector(const EvoProcessList<type>& plist)
00471 {
00472 r = 0;
00473 first = 0;
00474 sum = 0;
00475 randmachine = new EvoRandomizer<type>;
00476 processList = plist;
00477 }
00478 ~EvoSelector(){}
00479
00480 void command(EvoPopulation<type>& pop){
00481 sum = 0;
00482
00483
00484 typename EvoPopulation<type>::iterator it = pop.begin();
00485 typename EvoPopulation<type>::iterator it_temp;
00486
00487 while(it != pop.end())
00488 sum += ((*it++).fitness - pop.worst) ;
00489
00490
00491 it = pop.begin();
00492 while(it != pop.end())
00493 (*it).rfitness = ((*it++).fitness - pop.worst + 1)/sum;
00494
00495 it = pop.begin();
00496 it_temp = it;
00497
00498 (*it).cfitness = (*it).rfitness;
00499 it++;
00500
00501 while(it != pop.end())
00502 (*it).cfitness = (*it_temp++).cfitness + (*it++).rfitness;
00503
00504 double p = 0;
00505 typename EvoPopulation<type>::iterator it_inside = pop.begin();
00506
00507
00508 it = pop.begin();
00509 bool flag = true;
00510 first =0;
00511 while(it != pop.end()){
00512 it++;
00513 p = randmachine->random(0,1);
00514 it_inside = pop.begin();
00515
00516 it_temp = it_inside;
00517 flag = true;
00518 it_temp++;
00519 if( p < (*it_inside).cfitness ){
00520 sendToProcess((*it_inside));
00521
00522 }else{
00523 while( it_temp != pop.end() && (flag==true)){
00524
00525 if( (p >= (*it_inside).cfitness) && (p < (*it_temp).cfitness)){
00526 sendToProcess((*it_temp));
00527 flag = false;
00528 }
00529 it_inside++;
00530 it_temp++;
00531 }
00532 }
00533 }
00534 }
00535
00536 void sendToProcess(type& l){
00537
00538 ++first;
00539 if( first % 2 == 0 ){
00540
00541 if(l.fitness > r->fitness){
00542 l.generation += 1;
00543
00544
00545 processList.start(l,*r);
00546
00547
00548 }else{
00549 r->generation += 1;
00550
00551
00552 processList.start(*r,l);
00553
00554
00555 }
00556 }else{
00557
00558 r = &l;
00559 }
00560 }
00561
00562
00563 private:
00564 EvoProcessList<type> processList;
00565 EvoRandomizer<type>* randmachine;
00566
00567 double sum;
00568 int first;
00569
00570 type* r;
00571
00572 };
00573
00577 template<typename type>
00578 class EvoOperator : public EvoProcess<type>
00579 {
00580 public:
00581 EvoOperator(){}
00582 ~EvoOperator(){}
00583
00584 virtual void command(){};
00585 };
00586
00590 template<typename type>
00591 class EvoMutation : public EvoOperator<type>
00592 {
00593 public:
00594 EvoMutation(double d) : randmachine(new EvoRandomizer<type>) {
00595 pm = d;
00596 cout << "#Mutation Creation" << endl;
00597 }
00598 ~EvoMutation(){ cout << "#Mutation Destruction" <<endl;}
00599
00600 virtual void command(type& l, type& r){
00601
00602 control = randmachine->random(0,1);
00603 if(pm > control){
00604 point = randmachine->int_rand(0,r.size());
00605 (r[point]).value = randmachine->random(r[point].lbound,r[point].ubound);
00606 }
00607 }
00608 private:
00609 EvoRandomizer<type>* randmachine;
00610 double pm;
00611 double control;
00612 int point;
00613 };
00614
00615
00619 template<typename type>
00620 class EvoUnEqualMutation : public EvoOperator<type>
00621 {
00622 public:
00623 EvoUnEqualMutation(double d,double bi,unsigned int Ti) : randmachine(new EvoRandomizer<type>) {
00624 pm = d;
00625 b = bi;
00626 T = Ti;
00627 cout << "#Unequal Mutation Creation" << endl;
00628 }
00629 ~EvoUnEqualMutation(){ cout << "#Unequal Mutation Destruction" <<endl;}
00630
00631 virtual void command(type& l, type& r){
00632
00633 typename type::iterator it = r.begin();
00634 while( it != r.end() ){
00635 rnd = randmachine->random(0,1);
00636 if(pm > rnd){
00637 rnd = randmachine->random(0,1);
00638 if(rnd < 0.5)
00639 (*it).value += delta_function(r.generation,(*it).ubound - (*it).value);
00640 else
00641 (*it).value -= delta_function(r.generation,(*it).value - (*it).lbound);
00642 }
00643 it++;
00644 }
00645 }
00646
00647 double delta_function(unsigned int t, double y)
00648 {
00649 if(t > T) t=T-1;
00650
00651 rnd = randmachine->random(0,1);
00652 return y*(1-pow(rnd,(1-(t/T)*b)));
00653 }
00654 private:
00655 EvoRandomizer<type>* randmachine;
00656 double pm;
00657 double b;
00658 double rnd;
00659 unsigned int T;
00660
00661 };
00662
00663
00664 template<typename type>
00665 class EvoCrossover : public EvoOperator<type>
00666 {
00667 public:
00668 EvoCrossover(double p) : randmachine(new EvoRandomizer<type>) {
00669 pc = p;
00670 cout << "#Crossover Creation" << endl;
00671 }
00672 ~EvoCrossover(){ cout << "#Crossover Destruction" <<endl;}
00673
00674 void command(type& l, type& r){
00675
00676
00677
00678 if(pc > randmachine->random(0,1)){
00679 unsigned int lpoint = randmachine->int_rand(0,r.size());
00680 unsigned int rpoint = randmachine->int_rand(0,r.size());
00681 unsigned int temp = lpoint;
00682
00683 if(lpoint > rpoint){
00684 lpoint = rpoint;
00685 rpoint = temp;
00686 }
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 if(r.size()<3)
00699 (r[lpoint]).value = (l[lpoint]).value;
00700 else
00701 for(;lpoint <= rpoint;lpoint++)
00702 (r[lpoint]).value = (l[lpoint]).value;
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 }
00714 }
00715 private:
00716 EvoRandomizer<type>* randmachine;
00717 double pc;
00718 };
00719
00720 template<typename type>
00721 class EvoMeanCrossover : public EvoOperator<type>
00722 {
00723 public:
00724 EvoMeanCrossover(double p) : randmachine(new EvoRandomizer<type>) {
00725 pc = p;
00726 cout << "#Mean Crossover Creation" << endl;
00727 }
00728 ~EvoMeanCrossover(){ cout << "#Crossover Destruction" <<endl;}
00729
00730 void command(type& l, type& r){
00731
00732
00733 double rnd = randmachine->random(0,1);
00734
00735 if(pc > rnd){
00736
00737
00738 int lpoint = randmachine->int_rand(0,r.size());
00739 int rpoint = randmachine->int_rand(0,r.size());
00740 int temp = lpoint;
00741 if(lpoint > rpoint){
00742 lpoint = rpoint;
00743 rpoint = temp;
00744 }
00745
00746 if(r.size()<3)
00747 (r[lpoint]).value = (r[lpoint]).value + rnd*((l[lpoint]).value - (r[lpoint]).value);
00748 else
00749 for(;lpoint <= rpoint;lpoint++)
00750 (r[lpoint]).value = (r[lpoint]).value + rnd*((l[lpoint]).value - (r[lpoint]).value);
00751
00752
00753
00754
00755
00756
00757 }
00758 }
00759 private:
00760 EvoRandomizer<type>* randmachine;
00761 double pc;
00762 };
00763
00764 template<class T>
00765 class EvoProcessList : public std::list< EvoProcess<T>* >
00766 {
00767 public:
00768 EvoProcessList(){}
00769 ~EvoProcessList(){}
00770
00771 void start(T& first, T& second){
00772 typename EvoProcessList<T>::iterator it = begin();
00773 while(it != end() ){
00774 (*it)->command(first, second);
00775 it++;
00776 }
00777
00778 }
00779
00780 void start(EvoPopulation<T>& first){
00781 typename EvoProcessList<T>::iterator it = begin();
00782 while(it != end() ){
00783 (*it)->command(first);
00784 it++;
00785 }
00786
00787 }
00788
00789 };
00790
00791 #endif // EVOPOPULATION_H //