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