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;
00026 double beta;
00027 double c;
00028 double d;
00029 string cloningVersion;
00030 string selectionScheme;
00031
00032
00033 static bool sortPopulationByFitness (IndividualP ab1,IndividualP ab2) { return ( ab1->fitness->isBetterThan(ab2->fitness)); }
00034
00035
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 {
00053 name_ = "MyAlg";
00054 }
00055
00056
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
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
00133 if(state->getGenotypes().size() > 1)
00134 return true;
00135
00136
00137
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
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
00175 for( uint i = 0; i < deme->getSize(); i++ ) {
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
00187 uint clonesPerAntibody = beta * deme->getSize();
00188
00189
00190 for( uint i = 0; i < deme->getSize(); i++ )
00191 clones.push_back(deme->at(i));
00192
00193
00194 std::sort (clones.begin(), clones.end(), sortPopulationByFitness);
00195
00196
00197 clones.erase (clones.begin()+n,clones.end());
00198
00199 for( uint i = 0; i < n; i++ ){
00200 IndividualP antibody = clones.at(i);
00201
00202
00203 if (cloningVersion == "static"){
00204 for (uint j = 0; j < clonesPerAntibody; j++)
00205 clones.push_back(copy(antibody));
00206 }
00207
00208
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
00222 std::sort (clones.begin(), clones.end(), sortPopulationByFitness);
00223
00224 uint M;
00225 uint k;
00226
00227
00228 uint clonesPerAntibody = beta * deme->getSize();
00229
00230
00231 uint counter = 0;
00232 uint parentIndex = 0;
00233
00234 for( uint i = 0; i < clones.size(); i++ ){
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
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
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
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
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
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
00314 flp->initialize(state);
00315 evaluate(newAntibody);
00316
00317
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
00326 for( uint i = 0; i < clones.size(); i++ )
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
00340
00341
00342
00343 int main(int argc, char **argv)
00344 {
00345 StateP state (new State);
00346
00347 MyAlgP alg = (MyAlgP) new MyAlg;
00348 state->addAlgorithm(alg);
00349
00350
00351 state->setEvalOp(new FunctionMinEvalOp);
00352 state->initialize(argc, argv);
00353 state->run();
00354
00355 return 0;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430