• Main Page
  • Modules
  • Classes
  • Files
  • File List

D:/Projekt/ECF_trunk/examples/CEC/main_clonalg.cpp

00001 #include <ecf/ECF.h>
00002 #include "FunctionMinEvalOp.h"
00017 class MyAlg : public Algorithm
00018 {
00019 protected:
00020         
00021         double ubound;
00022         double lbound;
00023         uint dimension;
00024 
00025         uint n;                 // number of antibodies cloned every generation
00026         double beta;            // parameter which determines the number of clones for every antibody
00027         double c;               // mutation parameter
00028         double d;               // fraction of population regenerated every generation
00029         string cloningVersion;  // specifies whether to use static or proportional cloning
00030         string selectionScheme; // specifies which selection scheme to use CLONALG1 or CLONALG2
00031 
00032         // sort vector of antibodies in regards to their fitness
00033         static bool sortPopulationByFitness (IndividualP ab1,IndividualP ab2) { return ( ab1->fitness->isBetterThan(ab2->fitness)); }
00034 
00035         // sort vector of antibodies first by their antibody parents and then by their fitness
00036         static bool sortPopulationByParentAndFitness (IndividualP ab1,IndividualP ab2) 
00037         { 
00038             FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (ab1->getGenotype(1));
00039             double &parentAb1 = flp->realValue[0];
00040             flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (ab2->getGenotype(1));
00041             double &parentAb2 = flp->realValue[0];
00042 
00043             if (parentAb1 <parentAb2) return true;
00044             if (parentAb1 == parentAb2) return (ab1->fitness->isBetterThan(ab2->fitness));
00045     
00046             return false;
00047         }
00048 
00049 public:
00050         
00051         MyAlg()
00052         {       // define algorithm name
00053                 name_ = "MyAlg";
00054         }
00055 
00056         //register any parameters
00057         void registerParameters(StateP state)
00058         {   
00059             registerParameter(state, "n", (voidP) new uint(50), ECF::INT);
00060             registerParameter(state, "beta", (voidP) new double(0.1), ECF::DOUBLE);
00061             registerParameter(state, "c", (voidP) new double(0.2), ECF::DOUBLE);
00062             registerParameter(state, "d", (voidP) new double(0.0), ECF::DOUBLE);
00063             registerParameter(state, "cloningVersion", (voidP) new string("static"), ECF::STRING);
00064             registerParameter(state, "selectionScheme", (voidP) new string("CLONALG2"), ECF::STRING);
00065         }
00066 
00067         
00068         bool initialize(StateP state)
00069         {       
00070 
00071             voidP lBound = state->getGenotypes()[0]->getParameterValue(state, "lbound");
00072             lbound = *((double*) lBound.get());
00073 
00074             voidP uBound = state->getGenotypes()[0]->getParameterValue(state, "ubound");
00075             ubound = *((double*) uBound.get());
00076 
00077             voidP dimension_ = state->getGenotypes()[0]->getParameterValue(state, "dimension");
00078             dimension = *((uint*) dimension_.get());
00079             
00080             
00081             voidP populationSize_ = state->getRegistry()->getEntry("population.size");
00082             uint populationSize = *((uint*) populationSize_.get());
00083 
00084             voidP n_ = getParameterValue(state, "n");
00085             n = *((uint*) n_.get());
00086             if( n<1 || n>populationSize) {
00087                 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'n' to be an integer in range <0, population.size] ");
00088                 throw "";}
00089 
00090 
00091             voidP beta_ = getParameterValue(state, "beta");
00092             beta = *((double*) beta_.get());
00093             if( beta <= 0 ) {
00094                 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'beta' to be a double greater than 0");
00095                 throw "";}
00096 
00097 
00098             voidP c_ = getParameterValue(state, "c");
00099             c = *((double*) c_.get());
00100             if( c <= 0 ) {
00101                 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'c' to be a double greater than 0");
00102                 throw "";}
00103 
00104 
00105             voidP d_ = getParameterValue(state, "d");
00106             d = *((double*) d_.get());
00107             if( d<0 || d>1 ) {
00108                 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'd' to be a double in range [0, 1] ");
00109                 throw "";}
00110 
00111             voidP cloning_ = getParameterValue(state, "cloningVersion");
00112             cloningVersion = *((string*) cloning_.get());
00113             if( cloningVersion != "static" && cloningVersion != "proportional"  ) {
00114                 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'cloningVersion' to be either 'static' or a 'proportional'");
00115                 throw "";}
00116 
00117             voidP selection_ = getParameterValue(state, "selectionScheme");
00118             selectionScheme = *((string*) selection_.get());
00119             if( selectionScheme != "CLONALG1" && selectionScheme != "CLONALG2"  ) {
00120                 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'selectionScheme' to be either 'CLONALG1' or 'CLONALG2'");
00121                 throw "";}
00122                         
00123 
00124             // algorithm accepts a single FloatingPoint Genotype
00125             FloatingPointP flp (new FloatingPoint::FloatingPoint);
00126             if(state->getGenotypes()[0]->getName() != flp->getName()) {
00127                 ECF_LOG_ERROR(state, "Error: CLONALG algorithm accepts only a FloatingPoint genotype!");
00128                 throw ("");
00129             }
00130 
00131 
00132                 // ugly workaround za batch run, moramo jos vidjeti
00133                 if(state->getGenotypes().size() > 1)
00134                     return true;
00135 
00136 
00137             //add parentAntibody genotype
00138             if( selectionScheme == "CLONALG1"){
00139                 FloatingPointP flpoint[2];
00140                 for(uint iGen = 1; iGen < 2; iGen++) {
00141                     flpoint[iGen] = (FloatingPointP) new FloatingPoint::FloatingPoint;
00142                     state->setGenotype(flpoint[iGen]);
00143 
00144                     flpoint[iGen]->setParameterValue(state, "dimension", (voidP) new uint(1));                  
00145 
00146                     // initial value of age parameter should be (or as close as possible to) 0              
00147                     flpoint[iGen]->setParameterValue(state, "lbound", (voidP) new double(0));
00148                     flpoint[iGen]->setParameterValue(state, "ubound", (voidP) new double(0.01));
00149                     
00150                 }
00151                 ECF_LOG(state, 1, "CLONALG algorithm: added 1 FloatingPoint genotype (parentAntibody)");
00152             }
00153 
00154             return true;
00155         }
00156 
00157        
00158         bool advanceGeneration(StateP state, DemeP deme)
00159         {   
00160               std::vector<IndividualP> clones;
00161               if (selectionScheme == "CLONALG1")
00162                  markAntibodies(deme);
00163               cloningPhase(state, deme, clones);
00164               hypermutationPhase(state, deme, clones);
00165               selectionPhase(state, deme, clones);
00166               birthPhase(state, deme, clones);
00167               replacePopulation(state, deme, clones);
00168              
00169               return true;
00170         }
00171         
00172         
00173         bool markAntibodies(DemeP deme){
00174             //mark antibodies so the alg can know which clone belongs to which parent Antibody
00175             for( uint i = 0; i < deme->getSize(); i++ ) { // for each antibody
00176 
00177                     FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (deme->at(i)->getGenotype(1));
00178                     double &parentAb = flp->realValue[0];
00179                     parentAb = i;               
00180             }
00181             return true;
00182         }
00183 
00184         bool cloningPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00185         {   
00186             // calculate number of clones per antibody
00187             uint clonesPerAntibody = beta * deme->getSize();
00188 
00189             // storing all antibodies in a vector
00190             for( uint i = 0; i < deme->getSize(); i++ )  // for each antibody   
00191                 clones.push_back(deme->at(i));
00192 
00193             // sorting all antibodies
00194             std::sort (clones.begin(), clones.end(), sortPopulationByFitness);
00195             
00196             // leaving n best antibodies for cloning
00197             clones.erase (clones.begin()+n,clones.end());
00198             
00199             for( uint i = 0; i < n; i++ ){ // for each antibody in clones vector
00200                 IndividualP antibody = clones.at(i);
00201             
00202                 //static cloning : cloning each antibody beta*populationSize times
00203                 if (cloningVersion == "static"){
00204                     for (uint j = 0; j < clonesPerAntibody; j++) 
00205                         clones.push_back(copy(antibody));
00206                 }
00207 
00208                 //proportional cloning 
00209                 else{ 
00210                     uint proportionalCloneNo = clonesPerAntibody/(i+1);
00211                     for (uint j = 0; j < proportionalCloneNo ; j++) 
00212                         clones.push_back(copy(antibody));
00213                 }
00214             }
00215             
00216             return true;
00217         }
00218 
00219         bool hypermutationPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00220         {           
00221             // sorting all antibodies
00222             std::sort (clones.begin(), clones.end(), sortPopulationByFitness);
00223 
00224             uint M; // M - number of mutations of a single antibody 
00225             uint k;
00226 
00227             // calculate number of clones per antibody
00228             uint clonesPerAntibody = beta * deme->getSize();
00229 
00230             // these get used in case of proportional cloning
00231             uint counter = 0;       
00232             uint parentIndex = 0;
00233             
00234             for( uint i = 0; i < clones.size(); i++ ){ // for each antibody in vector clones
00235                 IndividualP antibody = clones.at(i);
00236                 
00237                 FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (antibody->getGenotype(0));
00238                 std::vector< double > &antibodyVars = flp->realValue;
00239                 
00240                 // inversely proportional hypermutation (better antibodies are mutated less)
00241                 if (cloningVersion == "static")
00242                     k = 1+ i/(clonesPerAntibody +1);
00243                 else{
00244                     if (counter == i){
00245                         parentIndex++;
00246                         counter += 1 + clonesPerAntibody/parentIndex;
00247                     }                   
00248                     k = parentIndex;
00249                 }
00250 
00251                 M = (int) ((1- 1/(double)(k)) * (c*dimension) + (c*dimension));
00252                                 
00253                 // mutate M times
00254                 for (uint j = 0; j < M; j++){
00255                     uint param = state->getRandomizer()->getRandomInteger((int)antibodyVars.size());
00256                     
00257                     double randDouble1 = state->getRandomizer()->getRandomDouble();
00258                     double randDouble2 = state->getRandomizer()->getRandomDouble();
00259                     double value = antibodyVars[param] + (1-2*randDouble1)* 0.2 *  (ubound - lbound) * pow(2, -16*randDouble2 );
00260                     
00261                     if (value > ubound)
00262                         value = ubound;
00263                     else if (value <lbound)
00264                         value = lbound;
00265 
00266                     //produce a mutation on the antibody 
00267                     antibodyVars[param] = value;
00268                 }
00269                 evaluate(antibody);
00270             }       
00271             return true;
00272         }
00273         
00274         bool selectionPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00275         {   
00276             if( selectionScheme == "CLONALG1") {
00277                 
00278                 std::sort (clones.begin(), clones.end(), sortPopulationByParentAndFitness);
00279             
00280                 int formerParent = -1;
00281                 std::vector<IndividualP> temp_clones;
00282 
00283                 for (uint i = 0; i < clones.size(); i++){
00284                     FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (clones.at(i)->getGenotype(1));
00285                     double &parentAb = flp->realValue[0];
00286                     if (formerParent != parentAb){
00287                         temp_clones.push_back(clones.at(i));
00288                         formerParent = parentAb;
00289                     }
00290                 }
00291                 clones = temp_clones;               
00292             }
00293 
00294             std::sort (clones.begin(), clones.end(), sortPopulationByFitness);
00295             uint selNumber = (uint)((1-d)*deme->getSize());
00296 
00297             //keep best (1-d)*populationSize antibodies ( or all if the number of clones is less than that )
00298             if(selNumber < clones.size())
00299                 clones.erase (clones.begin()+ selNumber, clones.end());
00300 
00301             return true;
00302         }
00303         
00304         bool birthPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00305         {   
00306             //  birthNumber - number of new antibodies randomly created and added 
00307             uint birthNumber = deme->getSize() - clones.size();
00308             
00309             IndividualP newAntibody = copy(deme->at(0));
00310             FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (newAntibody->getGenotype(0));
00311 
00312             for (uint i = 0; i<birthNumber; i++){
00313                 //create a random antibody
00314                 flp->initialize(state);
00315                 evaluate(newAntibody);
00316 
00317                 //add it to the clones vector
00318                 clones.push_back(copy(newAntibody));
00319             }           
00320             return true;
00321         }
00322 
00323         bool replacePopulation(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00324         {
00325             //replace population with the contents of clones vector
00326             for( uint i = 0; i < clones.size(); i++ ) // for each antibody
00327                 deme->replace(i, clones.at(i));
00328             
00329             clones.clear();
00330             
00331             return true;
00332         }
00333 
00334 };
00335 typedef boost::shared_ptr<MyAlg> MyAlgP;
00336 
00337 
00338 
00339 //this main() function optimizes a single COCO function (Id set in config file)
00340 //function Ids: noiseless 1-24, noisy 101-130
00341 
00342 
00343 int main(int argc, char **argv)
00344 {
00345     StateP state (new State);
00346     //set newAlg
00347     MyAlgP alg = (MyAlgP) new MyAlg;
00348     state->addAlgorithm(alg);
00349 
00350     // set the evaluation operator
00351     state->setEvalOp(new FunctionMinEvalOp);
00352     state->initialize(argc, argv);
00353     state->run();
00354 
00355     return 0;
00356 }
00357 
00358 
00359 
00360 //
00361 // this main() function iterates over multiple COCO functions and optimizes each one in turn
00362 // function Ids: noiseless 1-24, noisy 101-130
00363 //
00364 /*
00365 int main(int argc, char **argv)
00366 {
00367     // run for selected CEC functions
00368     for(uint function = 1; function <= 30; function++) {
00369 
00370         // read XML config
00371         std::ifstream fin(argv[1]);
00372         if (!fin) {
00373             std::cerr << "Error opening config file! (" << argv[1] << ")\n";
00374             return 1;
00375         }
00376 
00377         std::string xmlFile, temp;
00378         while (!fin.eof()) {
00379             getline(fin, temp);
00380             xmlFile += "\n" + temp;
00381         }
00382         fin.close();
00383 
00384         // set log and stats parameters
00385         std::string funcName = uint2str(function);
00386         std::string logName = "log", statsName = "stats";
00387         if(function < 10) {
00388             logName += "0";
00389             statsName += "0";
00390         }
00391         logName += uint2str(function) + ".txt";
00392         statsName += uint2str(function) + ".txt";
00393 
00394         // update in XML
00395         XMLResults results;
00396         XMLNode xConfig = XMLNode::parseString(xmlFile.c_str(), "ECF", &results);
00397         XMLNode registry = xConfig.getChildNode("Registry");
00398 
00399         XMLNode func = registry.getChildNodeWithAttribute("Entry", "key", "cec.function");
00400         func.updateText(funcName.c_str());
00401         XMLNode log = registry.getChildNodeWithAttribute("Entry", "key", "log.filename");
00402         log.updateText(logName.c_str());
00403         XMLNode stats = registry.getChildNodeWithAttribute("Entry", "key", "batch.statsfile");
00404         stats.updateText(statsName.c_str());
00405 
00406         // write back
00407         std::ofstream fout(argv[1]);
00408         fout << xConfig.createXMLString(true);
00409         fout.close();
00410 
00411 
00412         // finally, run ECF on single function
00413         StateP state (new State);
00414 
00415         // set the evaluation operator
00416         state->setEvalOp(new FunctionMinEvalOp);
00417 
00418 //      GenHookeJeevesP alg (new GenHookeJeeves);
00419 //      state->addAlgorithm(alg);
00420 
00421         MyAlgP alg = (MyAlgP) new MyAlg;
00422         state->addAlgorithm(alg);
00423 
00424         state->initialize(argc, argv);
00425         state->run();
00426     }
00427 
00428     return 0;
00429 }
00430 */

Generated on Tue Jul 8 2014 14:01:53 for ECF by  doxygen 1.7.1