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

D:/Projekt/ECF_trunk/examples/COCO/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             //add parentAntibody genotype
00131             if( selectionScheme == "CLONALG1"){
00132                 FloatingPointP flpoint[2];
00133                 for(uint iGen = 1; iGen < 2; iGen++) {
00134                     flpoint[iGen] = (FloatingPointP) new FloatingPoint::FloatingPoint;
00135                     state->setGenotype(flpoint[iGen]);
00136 
00137                     flpoint[iGen]->setParameterValue(state, "dimension", (voidP) new uint(1));                  
00138 
00139                     // initial value of age parameter should be (or as close as possible to) 0              
00140                     flpoint[iGen]->setParameterValue(state, "lbound", (voidP) new double(0));
00141                     flpoint[iGen]->setParameterValue(state, "ubound", (voidP) new double(0.01));
00142                     
00143                 }
00144                 ECF_LOG(state, 1, "CLONALG algorithm: added 1 FloatingPoint genotype (parentAntibody)");
00145             }
00146 
00147             return true;
00148         }
00149 
00150        
00151         bool advanceGeneration(StateP state, DemeP deme)
00152         {   
00153               std::vector<IndividualP> clones;
00154               if (selectionScheme == "CLONALG1")
00155                  markAntibodies(deme);
00156               cloningPhase(state, deme, clones);
00157               hypermutationPhase(state, deme, clones);
00158               selectionPhase(state, deme, clones);
00159               birthPhase(state, deme, clones);
00160               replacePopulation(state, deme, clones);
00161              
00162               return true;
00163         }
00164         
00165         
00166         bool markAntibodies(DemeP deme){
00167             //mark antibodies so the alg can know which clone belongs to which parent Antibody
00168             for( uint i = 0; i < deme->getSize(); i++ ) { // for each antibody
00169 
00170                     FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (deme->at(i)->getGenotype(1));
00171                     double &parentAb = flp->realValue[0];
00172                     parentAb = i;               
00173             }
00174             return true;
00175         }
00176 
00177         bool cloningPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00178         {   
00179             // calculate number of clones per antibody
00180             uint clonesPerAntibody = beta * deme->getSize();
00181 
00182             // storing all antibodies in a vector
00183             for( uint i = 0; i < deme->getSize(); i++ )  // for each antibody   
00184                 clones.push_back(deme->at(i));
00185 
00186             // sorting all antibodies
00187             std::sort (clones.begin(), clones.end(), sortPopulationByFitness);
00188             
00189             // leaving n best antibodies for cloning
00190             clones.erase (clones.begin()+n,clones.end());
00191             
00192             for( uint i = 0; i < n; i++ ){ // for each antibody in clones vector
00193                 IndividualP antibody = clones.at(i);
00194             
00195                 //static cloning : cloning each antibody beta*populationSize times
00196                 if (cloningVersion == "static"){
00197                     for (uint j = 0; j < clonesPerAntibody; j++) 
00198                         clones.push_back(copy(antibody));
00199                 }
00200 
00201                 //proportional cloning 
00202                 else{ 
00203                     uint proportionalCloneNo = clonesPerAntibody/(i+1);
00204                     for (uint j = 0; j < proportionalCloneNo ; j++) 
00205                         clones.push_back(copy(antibody));
00206                 }
00207             }
00208             
00209             return true;
00210         }
00211 
00212         bool hypermutationPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00213         {           
00214             // sorting all antibodies
00215             std::sort (clones.begin(), clones.end(), sortPopulationByFitness);
00216 
00217             uint M; // M - number of mutations of a single antibody 
00218             uint k;
00219 
00220             // calculate number of clones per antibody
00221             uint clonesPerAntibody = beta * deme->getSize();
00222 
00223             // these get used in case of proportional cloning
00224             uint counter = 0;       
00225             uint parentIndex = 0;
00226             
00227             for( uint i = 0; i < clones.size(); i++ ){ // for each antibody in vector clones
00228                 IndividualP antibody = clones.at(i);
00229                 
00230                 FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (antibody->getGenotype(0));
00231                 std::vector< double > &antibodyVars = flp->realValue;
00232                 
00233                 // inversely proportional hypermutation (better antibodies are mutated less)
00234                 if (cloningVersion == "static")
00235                     k = 1+ i/(clonesPerAntibody +1);
00236                 else{
00237                     if (counter == i){
00238                         parentIndex++;
00239                         counter += 1 + clonesPerAntibody/parentIndex;
00240                     }                   
00241                     k = parentIndex;
00242                 }
00243 
00244                 M = (int) ((1- 1/(double)(k)) * (c*dimension) + (c*dimension));
00245                                 
00246                 // mutate M times
00247                 for (uint j = 0; j < M; j++){
00248                     uint param = state->getRandomizer()->getRandomInteger((int)antibodyVars.size());
00249                     
00250                     double randDouble1 = state->getRandomizer()->getRandomDouble();
00251                     double randDouble2 = state->getRandomizer()->getRandomDouble();
00252                     double value = antibodyVars[param] + (1-2*randDouble1)* 0.2 *  (ubound - lbound) * pow(2, -16*randDouble2 );
00253                     
00254                     if (value > ubound)
00255                         value = ubound;
00256                     else if (value <lbound)
00257                         value = lbound;
00258 
00259                     //produce a mutation on the antibody 
00260                     antibodyVars[param] = value;
00261                 }
00262                 evaluate(antibody);
00263             }       
00264             return true;
00265         }
00266         
00267         bool selectionPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00268         {   
00269             if( selectionScheme == "CLONALG1") {
00270                 
00271                 std::sort (clones.begin(), clones.end(), sortPopulationByParentAndFitness);
00272             
00273                 int formerParent = -1;
00274                 std::vector<IndividualP> temp_clones;
00275 
00276                 for (uint i = 0; i < clones.size(); i++){
00277                     FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (clones.at(i)->getGenotype(1));
00278                     double &parentAb = flp->realValue[0];
00279                     if (formerParent != parentAb){
00280                         temp_clones.push_back(clones.at(i));
00281                         formerParent = parentAb;
00282                     }
00283                 }
00284                 clones = temp_clones;               
00285             }
00286 
00287             std::sort (clones.begin(), clones.end(), sortPopulationByFitness);
00288             uint selNumber = (uint)((1-d)*deme->getSize());
00289 
00290             //keep best (1-d)*populationSize antibodies ( or all if the number of clones is less than that )
00291             if(selNumber < clones.size())
00292                 clones.erase (clones.begin()+ selNumber, clones.end());
00293 
00294             return true;
00295         }
00296         
00297         bool birthPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00298         {   
00299             //  birthNumber - number of new antibodies randomly created and added 
00300             uint birthNumber = deme->getSize() - clones.size();
00301             
00302             IndividualP newAntibody = copy(deme->at(0));
00303             FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (newAntibody->getGenotype(0));
00304 
00305             for (uint i = 0; i<birthNumber; i++){
00306                 //create a random antibody
00307                 flp->initialize(state);
00308                 evaluate(newAntibody);
00309 
00310                 //add it to the clones vector
00311                 clones.push_back(copy(newAntibody));
00312             }           
00313             return true;
00314         }
00315 
00316         bool replacePopulation(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00317         {
00318             //replace population with the contents of clones vector
00319             for( uint i = 0; i < clones.size(); i++ ) // for each antibody
00320                 deme->replace(i, clones.at(i));
00321             
00322             clones.clear();
00323             
00324             return true;
00325         }
00326 
00327 };
00328 typedef boost::shared_ptr<MyAlg> MyAlgP;
00329 
00330 
00331 
00332 //this main() function optimizes a single COCO function (Id set in config file)
00333 //function Ids: noiseless 1-24, noisy 101-130
00334 
00335 
00336 //int main(int argc, char **argv)
00337 //{
00338 //  StateP state (new State);
00339 //  //set newAlg
00340 //  MyAlgP alg = (MyAlgP) new MyAlg;
00341 //  state->addAlgorithm(alg);
00342 //
00343 //  // set the evaluation operator
00344 //  state->setEvalOp(new FunctionMinEvalOp);
00345 //  state->initialize(argc, argv);
00346 //  state->run();
00347 //  int i;
00348 //  cin>>i;
00349 //
00350 //  return 0;
00351 //}
00352 
00353 
00354 
00355 //
00356 // this main() function iterates over multiple COCO functions and optimizes each one in turn
00357 // function Ids: noiseless 1-24, noisy 101-130
00358 //
00359 
00360 int main(int argc, char **argv)
00361 {
00362     // run for selected COCO functions
00363     for(uint function = 1; function < 25; function++) {
00364 
00365         // read XML config
00366         std::ifstream fin(argv[1]);
00367         if (!fin) {
00368             throw std::string("Error opening file! ");
00369         }
00370 
00371         std::string xmlFile, temp;
00372         while (!fin.eof()) {
00373             getline(fin, temp);
00374             xmlFile += "\n" + temp;
00375         }
00376         fin.close();
00377 
00378         // set log and stats parameters
00379         std::string funcName = uint2str(function);
00380         std::string logName = "log", statsName = "stats";
00381         if(function < 10) {
00382             logName += "0";
00383             statsName += "0";
00384         }
00385         logName += uint2str(function) + ".txt";
00386         statsName += uint2str(function) + ".txt";
00387 
00388         // update in XML
00389         XMLResults results;
00390         XMLNode xConfig = XMLNode::parseString(xmlFile.c_str(), "ECF", &results);
00391         XMLNode registry = xConfig.getChildNode("Registry");
00392 
00393         XMLNode func = registry.getChildNodeWithAttribute("Entry", "key", "coco.function");
00394         func.updateText(funcName.c_str());
00395         XMLNode log = registry.getChildNodeWithAttribute("Entry", "key", "log.filename");
00396         log.updateText(logName.c_str());
00397         XMLNode stats = registry.getChildNodeWithAttribute("Entry", "key", "batch.statsfile");
00398         stats.updateText(statsName.c_str());
00399 
00400         // write back
00401         std::ofstream fout(argv[1]);
00402         fout << xConfig.createXMLString(true);
00403         fout.close();
00404 
00405 
00406         // finally, run ECF on single function
00407         StateP state (new State);
00408 
00409         //set newAlg
00410         MyAlgP alg = (MyAlgP) new MyAlg;
00411         state->addAlgorithm(alg);
00412         // set the evaluation operator
00413         state->setEvalOp(new FunctionMinEvalOp);
00414 
00415         state->initialize(argc, argv);
00416         state->run();
00417     }
00418 
00419     return 0;
00420 }

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