Strona główna | Lista przestrzeni nazw | Hierarchia klas | Lista klas | Katalogi | Lista plików | Składowe klas

evolib.h

IdŸ do dokumentacji tego pliku.
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));// + 19.8*(x[1] -1)*(x[3] -1));
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){ /*cout << "Kreator" << endl;*/
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                         /*cout << " Kopy " << endl; */}
00133                         
00134                 ~EvoGen(){/*cout << "Dest" << endl; */}
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                 //      cout << "addGen: " << v << " "<< lb << " " << ub << endl;
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 ;//<< 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 //----------------RANDOMIZER-----------------------
00312 
00313 //class DoubleRandomizer : public 
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                 //      cout << "dziala" << endl;
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; }// const = 0;
00353                 virtual void command(type&){ cout << "Base" <<endl; } //const = 0;
00354                 virtual void command(type&,type&){ cout << "Base" <<endl; } //const = 0;
00355                 virtual void command(EvoPopulation<type>&){ cout << "Base" << endl; }
00356                 virtual void command(EvoPopulation<type>&,EvoPopulation<type>&){ cout << "Base" << endl; }
00357 };
00358 
00359 /*
00360 template<typename type>
00361 inline void EvoProcess<type>::command() const { cout << "Base" <<endl;}
00362 
00363 template<typename type>
00364 inline void EvoProcess<type>::command(type&) const { cout << "Base1" <<endl;}
00365 
00366 template<typename type>
00367 inline void EvoProcess<type>::command(type&,type&) const { cout << "Base2" <<endl;}
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                         //      cout <<"Fitness ="<<(*it).fitness << endl;
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 template<typename type>
00427 class EvoEvaluator : public EvoProcess<type>
00428 {
00429         public:
00430                 EvoEvaluator(double evalfunction(double[],int)) : predicatLikeFunction(evalfunction), decoder(new EvoCodec<type>) {}
00431                 ~EvoEvaluator(){}
00432                         
00433         virtual void command(EvoPopulation<type>& pop){ //cout << "Evaluator command" << endl;
00434                         pop.worst = 1000;
00435                         pop.best = -1000;
00436                         typename EvoPopulation<type>::iterator it = pop.begin();
00437                         while(it != pop.end()){
00438                                 (*it).fitness = predicatLikeFunction(decoder->decode(*it),(*it).size());
00439                                 
00440                                 if(pop.worst > (*it).fitness){
00441                                         pop.worst = (*it).fitness;
00442                                         pop.it_worst = it;
00443                                 }
00444                                 if(pop.best < (*it).fitness){
00445                                         pop.best = (*it).fitness;
00446                                         pop.it_best = it;
00447                                 }
00448                                 it++;
00449                         }
00450                 }
00451         
00452         private:
00453                 double (*predicatLikeFunction)(double[],int);
00454                 EvoCodec<type>* decoder;
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                 //      cout << "Selector command" << endl;
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 //                      typename EvoPopulation<type>::iterator it_mem = pop.begin(); // ten wylaczony test
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                                         //      cout << "TEST1" << endl;
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                         //cout << "TEST2"<<endl;
00538                         ++first;
00539                         if( first % 2 == 0 ){
00540                         //      cout << "TEST3"<<endl;
00541                                 if(l.fitness > r->fitness){
00542                                         l.generation += 1;
00543                                 //      l.show();
00544                                 //      r->show();
00545                                         processList.start(l,*r);
00546                                 //      l.show();
00547                                 //      r->show();
00548                                 }else{
00549                                         r->generation += 1;
00550                                 //      l.show();
00551                                 //      r->show();
00552                                         processList.start(*r,l);
00553                                 //      l.show();
00554                                 //      r->show();
00555                                 }
00556                         }else{
00557                         //      cout << "TEST4"<<endl;
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 //                      typename type::iterator it = r.begin();
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                 //      cout << "UNEQMUTATION" << endl;
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 //                      typename type::iterator it = r.begin();
00676 //                      typename type::iterator it_l = l.begin();
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                         //      if(rpoint - lpoint > 0.8*r.size())
00688                         //              rpoint = lpoint + ((int)(0.8*r.size()));
00689                         //      if(rpoint > r.size())
00690                         //              rpoint = r.size();
00691                                 
00692                         //      cout << "CROSSOVER" << endl;
00693                         //      cout << lpoint << " " << rpoint << endl;
00694                         //      r.show();
00695                         //      cout << " " << endl;
00696                         //      l.show();
00697                         //      cout << " " << endl;
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                         //                      cout << lpoint << endl;
00704                         //              }
00705                         //      r.show();
00706                         //              cout << " " << endl;
00707                         //      l.show();
00708                         //              cout << " " << endl;
00709                         //      cout << "CRO koniec" << endl;
00710                         //      l.show();
00711                         //              cout << endl;
00712                         //      r.show();
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 //                      typename type::iterator it = r.begin();
00732 //                      typename type::iterator it_l = l.begin();
00733                         double rnd = randmachine->random(0,1);
00734                         
00735                         if(pc > rnd){
00736                 //              cout << "MEAN CROSSOVER" << endl;
00737                         //      cout << r.size() << endl;
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                 //              cout << lpoint << " " << rpoint << endl;
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                                         //      cout << lpoint << endl;
00752                                         
00753                 //              cout << "koniec" << endl;
00754                         //      l.show();
00755                         //              cout << endl;
00756                         //      r.show();
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         //              cout << "End Process TwoArg" << endl;
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         //              cout << "End Process OneArg" << endl;
00787                 }
00788         
00789 };
00790 
00791 #endif // EVOPOPULATION_H //

Wygenerowano Thu Aug 25 18:44:50 2005 dla EvoLib programem  doxygen 1.4.1