00001 #include "ECF_base.h"
00002 #include "ECF_macro.h"
00003 #include "AlgClonalg.h"
00004 #include <cmath>
00005
00006
00007 Clonalg::Clonalg()
00008 {
00009
00010 name_ = "Clonalg";
00011
00012 areGenotypesAdded_ = false;
00013 }
00014
00015
00016 void Clonalg::registerParameters(StateP state)
00017 {
00018 registerParameter(state, "n", (voidP) new uint(100), ECF::INT,
00019 "number of antibodies cloned every generation (default: 100)");
00020 registerParameter(state, "beta", (voidP) new double(1), ECF::DOUBLE,
00021 "number of clones (percentage) for every antibody (default: 1.0)");
00022 registerParameter(state, "c", (voidP) new double(0.2), ECF::DOUBLE,
00023 "mutation rate (default: 0.2)");
00024 registerParameter(state, "d", (voidP) new double(0.0), ECF::DOUBLE,
00025 "fraction of population regenerated every generation (default: 0)");
00026 registerParameter(state, "cloningVersion", (voidP) new std::string("proportional"), ECF::STRING,
00027 "cloning version, static or proportional (default: proportional)");
00028 registerParameter(state, "selectionScheme", (voidP) new std::string("CLONALG1"), ECF::STRING,
00029 "which selection scheme to use, CLONALG1 or CLONALG2 (default: CLONALG1)");
00030 }
00031
00032
00033 bool Clonalg::initialize(StateP state)
00034 {
00035 voidP lBound = state->getGenotypes()[0]->getParameterValue(state, "lbound");
00036 lbound = *((double*) lBound.get());
00037
00038 voidP uBound = state->getGenotypes()[0]->getParameterValue(state, "ubound");
00039 ubound = *((double*) uBound.get());
00040
00041 voidP dimension_ = state->getGenotypes()[0]->getParameterValue(state, "dimension");
00042 dimension = *((uint*) dimension_.get());
00043
00044
00045 voidP populationSize_ = state->getRegistry()->getEntry("population.size");
00046 uint populationSize = *((uint*) populationSize_.get());
00047
00048 voidP n_ = getParameterValue(state, "n");
00049 n = *((uint*) n_.get());
00050 if( n<1 || n>populationSize) {
00051 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'n' to be an integer in range <0, population.size] ");
00052 throw "";}
00053
00054
00055 voidP beta_ = getParameterValue(state, "beta");
00056 beta = *((double*) beta_.get());
00057 if( beta <= 0 ) {
00058 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'beta' to be a double greater than 0");
00059 throw "";}
00060
00061
00062 voidP c_ = getParameterValue(state, "c");
00063 c = *((double*) c_.get());
00064 if( c <= 0 ) {
00065 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'c' to be a double greater than 0");
00066 throw "";}
00067
00068
00069 voidP d_ = getParameterValue(state, "d");
00070 d = *((double*) d_.get());
00071 if( d<0 || d>1 ) {
00072 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'd' to be a double in range [0, 1] ");
00073 throw "";}
00074
00075 voidP cloning_ = getParameterValue(state, "cloningVersion");
00076 cloningVersion = *((std::string*) cloning_.get());
00077 if( cloningVersion != "static" && cloningVersion != "proportional" ) {
00078 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'cloningVersion' to be either 'static' or a 'proportional'");
00079 throw "";}
00080
00081 voidP selection_ = getParameterValue(state, "selectionScheme");
00082 selectionScheme = *((std::string*) selection_.get());
00083 if( selectionScheme != "CLONALG1" && selectionScheme != "CLONALG2" ) {
00084 ECF_LOG(state, 1, "Error: CLONALG requires parameter 'selectionScheme' to be either 'CLONALG1' or 'CLONALG2'");
00085 throw "";}
00086
00087
00088
00089 FloatingPointP flp (new FloatingPoint::FloatingPoint);
00090 if(state->getGenotypes()[0]->getName() != flp->getName()) {
00091 ECF_LOG_ERROR(state, "Error: CLONALG algorithm accepts only a FloatingPoint genotype!");
00092 throw ("");
00093 }
00094
00095
00096 if(areGenotypesAdded_)
00097 return true;
00098
00099
00100 if( selectionScheme == "CLONALG1"){
00101 FloatingPointP flpoint[2];
00102 for(uint iGen = 1; iGen < 2; iGen++) {
00103 flpoint[iGen] = (FloatingPointP) new FloatingPoint::FloatingPoint;
00104 state->setGenotype(flpoint[iGen]);
00105
00106 flpoint[iGen]->setParameterValue(state, "dimension", (voidP) new uint(1));
00107
00108
00109 flpoint[iGen]->setParameterValue(state, "lbound", (voidP) new double(0));
00110 flpoint[iGen]->setParameterValue(state, "ubound", (voidP) new double(0.01));
00111
00112 }
00113 ECF_LOG(state, 1, "CLONALG algorithm: added 1 FloatingPoint genotype (parentAntibody)");
00114 }
00115
00116
00117 areGenotypesAdded_ = true;
00118
00119 return true;
00120 }
00121
00122
00123 bool Clonalg::advanceGeneration(StateP state, DemeP deme)
00124 {
00125 std::vector<IndividualP> clones;
00126 if (selectionScheme == "CLONALG1")
00127 markAntibodies(deme);
00128 cloningPhase(state, deme, clones);
00129 hypermutationPhase(state, deme, clones);
00130 selectionPhase(state, deme, clones);
00131 birthPhase(state, deme, clones);
00132 replacePopulation(state, deme, clones);
00133
00134 return true;
00135 }
00136
00137
00139 bool Clonalg::markAntibodies(DemeP deme)
00140 {
00141 for( uint i = 0; i < deme->getSize(); i++ ) {
00142 FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (deme->at(i)->getGenotype(1));
00143 double &parentAb = flp->realValue[0];
00144 parentAb = i;
00145 }
00146 return true;
00147 }
00148
00149
00150 bool Clonalg::cloningPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00151 {
00152
00153 uint clonesPerAntibody = (uint) (beta * deme->getSize());
00154
00155
00156 for( uint i = 0; i < deme->getSize(); i++ )
00157 clones.push_back(deme->at(i));
00158
00159
00160 std::sort (clones.begin(), clones.end(), sortPopulationByFitness);
00161
00162
00163 clones.erase (clones.begin()+n,clones.end());
00164
00165 for( uint i = 0; i < n; i++ ) {
00166 IndividualP antibody = clones.at(i);
00167
00168
00169 if (cloningVersion == "static") {
00170 for (uint j = 0; j < clonesPerAntibody; j++)
00171 clones.push_back(copy(antibody));
00172 }
00173
00174
00175 else {
00176 uint proportionalCloneNo = clonesPerAntibody/(i+1);
00177 for (uint j = 0; j < proportionalCloneNo ; j++)
00178 clones.push_back(copy(antibody));
00179 }
00180 }
00181
00182 return true;
00183 }
00184
00185
00186 bool Clonalg::hypermutationPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00187 {
00188
00189 std::sort (clones.begin(), clones.end(), sortPopulationByFitness);
00190
00191 uint M;
00192 uint k;
00193
00194
00195 uint clonesPerAntibody = (uint) (beta * deme->getSize());
00196
00197
00198 uint counter = 0;
00199 uint parentIndex = 0;
00200
00201 for( uint i = 0; i < clones.size(); i++ ) {
00202 IndividualP antibody = clones.at(i);
00203
00204 FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (antibody->getGenotype(0));
00205 std::vector< double > &antibodyVars = flp->realValue;
00206
00207
00208 if (cloningVersion == "static")
00209 k = 1+ i/(clonesPerAntibody +1);
00210 else{
00211 if (counter == i) {
00212 parentIndex++;
00213 counter += 1 + clonesPerAntibody/parentIndex;
00214 }
00215 k = parentIndex;
00216 }
00217
00218 M = (int) ((1- 1/(double)(k)) * (c*dimension) + (c*dimension));
00219
00220
00221 for (uint j = 0; j < M; j++) {
00222 uint param = state->getRandomizer()->getRandomInteger((int)antibodyVars.size());
00223
00224 double randDouble1 = state->getRandomizer()->getRandomDouble();
00225 double randDouble2 = state->getRandomizer()->getRandomDouble();
00226 double value = antibodyVars[param] + (1-2*randDouble1)* 0.2 * (ubound - lbound) * pow(2, -16*randDouble2 );
00227
00228 if (value > ubound)
00229 value = ubound;
00230 else if (value <lbound)
00231 value = lbound;
00232
00233
00234 antibodyVars[param] = value;
00235 }
00236 evaluate(antibody);
00237 }
00238 return true;
00239 }
00240
00241
00242 bool Clonalg::selectionPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00243 {
00244 if( selectionScheme == "CLONALG1") {
00245
00246 std::sort (clones.begin(), clones.end(), sortPopulationByParentAndFitness);
00247
00248 int formerParent = -1;
00249 std::vector<IndividualP> temp_clones;
00250
00251 for (uint i = 0; i < clones.size(); i++) {
00252 FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (clones.at(i)->getGenotype(1));
00253 double &parentAb = flp->realValue[0];
00254 if (formerParent != parentAb) {
00255 temp_clones.push_back(clones.at(i));
00256 formerParent = (int) parentAb;
00257 }
00258 }
00259 clones = temp_clones;
00260 }
00261
00262 std::sort (clones.begin(), clones.end(), sortPopulationByFitness);
00263 uint selNumber = (uint)((1-d)*deme->getSize());
00264
00265
00266 if(selNumber < clones.size())
00267 clones.erase (clones.begin()+ selNumber, clones.end());
00268
00269 return true;
00270 }
00271
00272
00273 bool Clonalg::birthPhase(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00274 {
00275
00276 uint birthNumber = deme->getSize() - clones.size();
00277
00278 IndividualP newAntibody = copy(deme->at(0));
00279 FloatingPointP flp = boost::dynamic_pointer_cast<FloatingPoint::FloatingPoint> (newAntibody->getGenotype(0));
00280
00281 for (uint i = 0; i<birthNumber; i++) {
00282
00283 flp->initialize(state);
00284 evaluate(newAntibody);
00285
00286
00287 clones.push_back(copy(newAntibody));
00288 }
00289 return true;
00290 }
00291
00292
00294 bool Clonalg::replacePopulation(StateP state, DemeP deme, std::vector<IndividualP> &clones)
00295 {
00296 for( uint i = 0; i < clones.size(); i++ )
00297 deme->replace(i, clones.at(i));
00298
00299 clones.clear();
00300
00301 return true;
00302 }