00001 #include "ECF_base.h"
00002 #include "ECF_macro.h"
00003 #include "AlgEvolutionStrategy.h"
00004 #include "SelBestOp.h"
00005 #include "SelRandomOp.h"
00006 #include <algorithm>
00007
00008
00009 EvolutionStrategy::EvolutionStrategy()
00010 {
00011
00012 name_ = "EvolutionStrategy";
00013
00014
00015 selBestOp_ = static_cast<SelectionOperatorP> (new SelBestOp);
00016 selRandomOp_ = static_cast<SelectionOperatorP> (new SelRandomOp);
00017 }
00018
00019
00020 void EvolutionStrategy::registerParameters(StateP state)
00021 {
00022 registerParameter(state, "lambda", (voidP) new uint(4), ECF::UINT,
00023 "number of offspring created in each iteration (default: 4)");
00024 registerParameter(state, "rho", (voidP) new uint(1), ECF::UINT,
00025 "number of parents used to create an offspring; may be 1 or 2 (default: 1)");
00026 registerParameter(state, "mu", (voidP) new uint(1), ECF::UINT,
00027 "the size of parent population (default: 1)");
00028 registerParameter(state, "selection", (voidP) new std::string("plus"), ECF::STRING,
00029 "selection scheme: \"plus\", uses both parents and offspring) or \"comma\", uses just offspring (default: plus)");
00030 }
00031
00032
00033 bool EvolutionStrategy::initialize(StateP state)
00034 {
00035
00036 selBestOp_->initialize(state);
00037 selRandomOp_->initialize(state);
00038
00039
00040 voidP sizep = getParameterValue(state, "lambda");
00041 lambda_ = *((uint*) sizep.get());
00042
00043 voidP rhop = getParameterValue(state, "rho");
00044 rho_ = *((uint*) rhop.get());
00045
00046 if(rho_ < 1 || rho_ > 2) {
00047 ECF_LOG_ERROR(state, "Error: number of parents to create an offspring in EvolutionStrategy can only be 1 or 2!");
00048 throw "";
00049 }
00050
00051 voidP mup = getParameterValue(state, "mu");
00052 mu_ = *((uint*) mup.get());
00053
00054 if(mu_ < rho_) {
00055 ECF_LOG_ERROR(state, "Error: size of parent population in EvolutionStrategy must be greater than number of parents to create an offspring!");
00056 throw "";
00057 }
00058
00059
00060 voidP sptr = state->getRegistry()->getEntry("population.size");
00061 uint demeSize = *((uint*) sptr.get());
00062 if(demeSize % mu_ != 0 || mu_ < 1) {
00063 ECF_LOG_ERROR(state, "Error: \"population.size\" parameter must be a multiple of size of parent population (mu) in EvolutionStrategy algorithm!");
00064 throw "";
00065 }
00066
00067 voidP selp = getParameterValue(state, "selection");
00068 std::string sels = *((std::string*) selp.get());
00069 if(sels == "plus")
00070 plusSelection_ = true;
00071 else if(sels == "comma")
00072 plusSelection_ = false;
00073 else {
00074 ECF_LOG_ERROR(state, "Error: selection type in EvolutionStrategy can only be \"plus\" or \"comma\"!");
00075 throw "";
00076 }
00077
00078 if(plusSelection_ == false && lambda_ <= mu_) {
00079 ECF_LOG_ERROR(state, "Error: offspring number (lambda) in comma EvolutionStrategy must be greater than the number of parents (mu)!");
00080 throw "";
00081 }
00082
00083 return true;
00084 }
00085
00086
00087 bool EvolutionStrategy::advanceGeneration(StateP state, DemeP deme)
00088 {
00089 subPopulations_ = (uint) deme->size() / mu_;
00090
00091
00092 for(uint subPopulation = 0; subPopulation < subPopulations_; subPopulation++) {
00093
00094
00095 uint firstInd = subPopulation * mu_;
00096 uint lastInd = (subPopulation + 1) * mu_;
00097
00098
00099 std::vector<IndividualP> parents;
00100 for(uint ind = firstInd; ind < lastInd; ind++)
00101 parents.push_back(deme->at(ind));
00102
00103
00104 std::vector<IndividualP> offspring;
00105 for(uint iChild = 0; iChild < lambda_; iChild++) {
00106
00107 IndividualP child;
00108
00109 if(rho_ == 1) {
00110 IndividualP parent = selRandomOp_->select(parents);
00111 child = copy(parent);
00112 mutation_->mutate(child);
00113 }
00114
00115 else if(rho_ == 2) {
00116 IndividualP p1 = selRandomOp_->select(parents);
00117 IndividualP p2 = p1;
00118 while(p1 == p2)
00119 p2 = selRandomOp_->select(parents);
00120 child = copy(p1);
00121 mate(p1, p2, child);
00122 }
00123 offspring.push_back(child);
00124
00125 evaluate(child);
00126 }
00127
00128
00129 std::vector<IndividualP> selPool;
00130 if(plusSelection_) {
00131
00132 selPool = parents;
00133 selPool.insert(selPool.end(), offspring.begin(), offspring.end());
00134 }
00135 else
00136
00137 selPool = offspring;
00138
00139
00140 std::sort(selPool.begin(), selPool.end(), &EvolutionStrategy::compare);
00141
00142
00143 uint selected = 0;
00144 for(uint ind = firstInd; ind < lastInd; ind++, selected++)
00145 replaceWith(ind, selPool[selected]);
00146 }
00147
00148 return true;
00149 }