ECF 1.5
AlgEvolutionStrategy.cpp
1#include "ECF_base.h"
2#include "ECF_macro.h"
3#include "AlgEvolutionStrategy.h"
4#include "SelBestOp.h"
5#include "SelRandomOp.h"
6#include <algorithm>
7
8
9EvolutionStrategy::EvolutionStrategy()
10{
11 // define algorithm name
12 name_ = "EvolutionStrategy";
13
14 // create selection operators needed
15 selBestOp_ = static_cast<SelectionOperatorP> (new SelBestOp);
16 selRandomOp_ = static_cast<SelectionOperatorP> (new SelRandomOp);
17}
18
19
21{
22 registerParameter(state, "lambda", (voidP) new uint(4), ECF::UINT,
23 "number of offspring created in each iteration (default: 4)");
24 registerParameter(state, "rho", (voidP) new uint(1), ECF::UINT,
25 "number of parents used to create an offspring; may be 1 or 2 (default: 1)");
26 registerParameter(state, "mu", (voidP) new uint(1), ECF::UINT,
27 "the size of parent population (default: 1)");
28 registerParameter(state, "selection", (voidP) new std::string("plus"), ECF::STRING,
29 "selection scheme: \"plus\", uses both parents and offspring) or \"comma\", uses just offspring (default: plus)");
30}
31
32
34{
35 // initialize all operators
36 selBestOp_->initialize(state);
37 selRandomOp_->initialize(state);
38
39 // read parameter values
40 voidP sizep = getParameterValue(state, "lambda");
41 lambda_ = *((uint*) sizep.get());
42
43 voidP rhop = getParameterValue(state, "rho");
44 rho_ = *((uint*) rhop.get());
45
46 if(rho_ < 1 || rho_ > 2) {
47 ECF_LOG_ERROR(state, "Error: number of parents to create an offspring in EvolutionStrategy can only be 1 or 2!");
48 throw "";
49 }
50
51 voidP mup = getParameterValue(state, "mu");
52 mu_ = *((uint*) mup.get());
53
54 if(mu_ < rho_) {
55 ECF_LOG_ERROR(state, "Error: size of parent population in EvolutionStrategy must be greater than number of parents to create an offspring!");
56 throw "";
57 }
58
59
60 voidP sptr = state->getRegistry()->getEntry("population.size");
61 uint demeSize = *((uint*) sptr.get());
62 if(demeSize % mu_ != 0 || mu_ < 1) {
63 ECF_LOG_ERROR(state, "Error: \"population.size\" parameter must be a multiple of size of parent population (mu) in EvolutionStrategy algorithm!");
64 throw "";
65 }
66
67 voidP selp = getParameterValue(state, "selection");
68 std::string sels = *((std::string*) selp.get());
69 if(sels == "plus")
70 plusSelection_ = true;
71 else if(sels == "comma")
72 plusSelection_ = false;
73 else {
74 ECF_LOG_ERROR(state, "Error: selection type in EvolutionStrategy can only be \"plus\" or \"comma\"!");
75 throw "";
76 }
77
78 if(plusSelection_ == false && lambda_ <= mu_) {
79 ECF_LOG_ERROR(state, "Error: offspring number (lambda) in comma EvolutionStrategy must be greater than the number of parents (mu)!");
80 throw "";
81 }
82
83 return true;
84}
85
86
87bool EvolutionStrategy::advanceGeneration(StateP state, DemeP deme)
88{
89 subPopulations_ = (uint) deme->size() / mu_;
90
91 // repeat the same ES for each parent subpopulation
92 for(uint subPopulation = 0; subPopulation < subPopulations_; subPopulation++) {
93
94 // use appropriate portion of the deme
95 uint firstInd = subPopulation * mu_;
96 uint lastInd = (subPopulation + 1) * mu_;
97
98 // construct parent pool
99 std::vector<IndividualP> parents;
100 for(uint ind = firstInd; ind < lastInd; ind++)
101 parents.push_back(deme->at(ind));
102
103 // create offspring pool
104 std::vector<IndividualP> offspring;
105 for(uint iChild = 0; iChild < lambda_; iChild++) {
106 // randomly select rho parents, create one child
107 IndividualP child;
108 // use mutation
109 if(rho_ == 1) {
110 IndividualP parent = selRandomOp_->select(parents);
111 child = copy(parent);
112 mutation_->mutate(child);
113 }
114 // use crossover
115 else if(rho_ == 2) {
116 IndividualP p1 = selRandomOp_->select(parents);
117 IndividualP p2 = p1;
118 while(p1 == p2)
119 p2 = selRandomOp_->select(parents);
120 child = copy(p1);
121 mate(p1, p2, child);
122 }
123 offspring.push_back(child);
124 // evaluate offspring
125 evaluate(child);
126 }
127
128 // construct selection pool for new generation parents
129 std::vector<IndividualP> selPool;
130 if(plusSelection_) {
131 // arrange selection pool from both best parents and offspring
132 selPool = parents;
133 selPool.insert(selPool.end(), offspring.begin(), offspring.end());
134 }
135 else
136 // select from offspring only
137 selPool = offspring;
138
139 // sort by fitness (best first)
140 std::sort(selPool.begin(), selPool.end(), &EvolutionStrategy::compare);
141
142 // replace new generation in deme
143 uint selected = 0;
144 for(uint ind = firstInd; ind < lastInd; ind++, selected++)
145 replaceWith(ind, selPool[selected]);
146 }
147
148 return true;
149}
IndividualP copy(IndividualP source)
Helper function: make a copy of an individual.
Definition: Algorithm.h:291
std::string name_
algorithm name
Definition: Algorithm.h:23
bool registerParameter(StateP state, std::string name, voidP value, enum ECF::type T, std::string description="")
Helper function: register a single parameter with the system.
Definition: Algorithm.h:35
voidP getParameterValue(StateP state, std::string name)
Helper function: get parameter value from the system.
Definition: Algorithm.h:46
bool mate(IndividualP p1, IndividualP p2, IndividualP child)
Helper function: crossover two individuals.
Definition: Algorithm.h:285
void replaceWith(IndividualP oldInd, IndividualP newInd)
Helper function: replace an individual in current deme.
Definition: Algorithm.h:187
MutationP mutation_
sptr to container of mutation operators (set by the system)
Definition: Algorithm.h:81
void evaluate(IndividualP ind)
Helper function: evaluate an individual.
Definition: Algorithm.h:157
uint rho_
number of parents (1 or 2)
uint mu_
the size of the parent population
void registerParameters(StateP state)
Register algorithm's parameters (if any).
uint lambda_
number of offspring
bool initialize(StateP state)
Initialize the algorithm, read parameters from the system, do a sanity check.
bool advanceGeneration(StateP state, DemeP deme)
Perform a single generation on a single deme.
uint subPopulations_
how many parent populations are in a deme
bool plusSelection_
type of selection (plus or comma)
Best individual selection operator.
Definition: SelBestOp.h:10
Random individual selection operator.
Definition: SelRandomOp.h:12