ECF 1.5
Population.cpp
1#include "ECF_base.h"
2#include <string.h>
3
4
5Population::Population()
6{
7 hof_ = static_cast<HallOfFameP> (new HallOfFame);
8 stats_ = static_cast<StatCalcP> (new StatCalc);
9
10 nIndividuals_ = 100;
11 nDemes_ = 1;
12 myDemeIndex_ = 0;
13}
14
15
17{
18 uint *sizep = new uint(100);
19 state->getRegistry()->registerEntry("population.size", (voidP) sizep, ECF::UINT,
20 "number of individuals (default: 100)");
21 uint *demep = new uint(1);
22 state->getRegistry()->registerEntry("population.demes", (voidP) demep, ECF::UINT,
23 "number of demes (default: 1)");
24
25 stats_->registerParameters(state);
26}
27
28
29#ifndef _MPI // slijedna verzija
30
31
35bool Population::initialize(StateP state)
36{
37 state_ = state;
38 this->clear();
39
40 hof_ = static_cast<HallOfFameP> (new HallOfFame);
41 hof_->initialize(state);
42
43 stats_ = static_cast<StatCalcP> (new StatCalc);
44 stats_->initialize(state);
45
46 voidP sptr = state->getRegistry()->getEntry("population.size");
47 nIndividuals_ = *((uint*) sptr.get());
48 sptr = state->getRegistry()->getEntry("population.demes");
49 nDemes_ = *((uint*) sptr.get());
50
51 for(uint i = 0; i < nDemes_; i++){
52 this->push_back(static_cast<DemeP> (new Deme));
53 this->back()->getSize() = nIndividuals_;
54 this->back()->initialize(state);
55 }
56
57 return true;
58}
59
60
65void Population::read(XMLNode &xPopulation)
66{
67 XMLNode xHof = xPopulation.getChildNode(0);
68 this->hof_->read(xHof);
69
70 for(uint i = 0; i < this->size(); i++) {
71 XMLNode xDeme = xPopulation.getChildNode((int)i + 1);
72 this->at(i)->read(xDeme);
73 }
74}
75
76
80void Population::write(XMLNode &xPopulation)
81{
82 xPopulation = XMLNode::createXMLTopNode(NODE_POPULATION);
83 xPopulation.addAttribute("size", uint2str(nDemes_).c_str()); // number of demes
84
85 XMLNode xHoF;
86 hof_->write(xHoF);
87 xPopulation.addChild(xHoF);
88
89 for(uint iDeme = 0; iDeme < nDemes_; iDeme++) {
90 XMLNode xDeme;
91 this->at(iDeme)->write(xDeme);
92 xPopulation.addChild(xDeme);
93 }
94}
95
96
101{
102 ECF_LOG(state_, 4, "Population: updating HoF and statistics of all demes");
103
104 // operate statistics on all demes
105 for(uint iDeme = 0; iDeme < this->size(); iDeme++) {
106 DemeP deme = this->at(iDeme);
107 deme->stats_->operate(*(deme));
108 ECF_LOG(state_, 3, "Deme: " + uint2str(iDeme));
109 deme->stats_->log();
110 }
111
112 // copy stats from first deme, update with others
113 stats_->copyStats(this->at(0)->stats_);
114
115 if(this->nDemes_ > 1) {
116 for(uint iDeme = 1; iDeme < this->size(); iDeme++)
117 stats_->update(this->at(iDeme)->stats_->getStats());
118 ECF_LOG(state_, 3, "Population:");
119 stats_->log();
120 }
121
122 // gather HoF
123 std::vector<IndividualP> pool;
124 for(uint iDeme = 0; iDeme < this->size(); iDeme++) {
125 this->at(iDeme)->hof_->operate(*(this->at(iDeme)));
126 std::vector<IndividualP> bestOfDeme = this->at(iDeme)->hof_->getBest();
127 for(uint i = 0; i < bestOfDeme.size(); i++)
128 pool.push_back(bestOfDeme[i]);
129 hof_->operate(pool);
130 }
131}
132
133
134#else // _MPI - paralelna verzija
135
136
140bool Population::initialize(StateP state)
141{
142 this->clear();
143 state_ = state;
144
145 voidP sptr = state->getRegistry()->getEntry("population.size");
146 nIndividuals_ = *((uint*) sptr.get());
147 sptr = state->getRegistry()->getEntry("population.demes");
148 nDemes_ = *((uint*) sptr.get());
149
150 hof_ = static_cast<HallOfFameP> (new HallOfFame);
151 hof_->initialize(state);
152
153 stats_ = static_cast<StatCalcP> (new StatCalc);
154 stats_->initialize(state);
155
156 // single deme:
157 if(nDemes_ == 1) {
158 this->push_back(static_cast<DemeP> (new Deme));
159 this->back()->getSize() = nIndividuals_;
160 this->back()->initialize(state);
161 myDemeIndex_ = 0;
162 return true;
163 }
164
165 // multiple demes:
166 myDemeIndex_ = state->getCommunicator()->createDemeCommunicator(nDemes_);
167 this->push_back(static_cast<DemeP> (new Deme));
168 this->back()->getSize() = nIndividuals_;
169 this->back()->initialize(state);
170
171 return true;
172}
173
174
179{
180 ECF_LOG(state_, 4, "Population: updating HoF and statistics of all demes");
181 // every process 'processes' its local deme
182 ECF_LOG(state_, 3, "Deme: " + uint2str(getLocalDemeId()));
183 this->at(0)->hof_->operate(*(getLocalDeme()));
184
185 // operate hof and stats on local deme
186 std::vector<IndividualP> bestPool = this->at(0)->hof_->getBest();
187 hof_->operate(bestPool);
188
189 this->at(0)->stats_->operate(*(getLocalDeme()));
190 stats_->copyStats(this->at(0)->stats_);
191 stats_->log();
192
193 // update with remote demes
194 if(nDemes_ > 1) { // vise demova - svaki lokalni proces 0 dodje ovdje
195 // globalni proces 0 prima hof-ove i statistiku od ostalih deme mastera
196 if(state_->getCommunicator()->getCommGlobalRank() == 0) {
197
198 std::vector<IndividualP> bestPool, received;
199 bestPool = this->at(0)->hof_->getBest(); // uzmi moj hof za pocetak
200
201 for(uint iDeme = 1; iDeme < nDemes_; iDeme++) { // dodaj ostale
202 received = state_->getCommunicator()->recvIndividualsGlobal();
203 for(uint ind = 0; ind < received.size(); ind++)
204 bestPool.push_back(received[ind]);
205 }
206
207 hof_->operate(bestPool); // konacno, odredi globalni hof
208
209 // gather statistics
210 std::vector<double> statValues;
211 for(uint iDeme = 1; iDeme < nDemes_; iDeme++) {
212 statValues = state_->getCommunicator()->recvValuesGlobal();
213 stats_->update(statValues);
214 }
215 ECF_LOG(state_, 3, "Population: ");
216 stats_->log();
217 }
218 else { // saljem globalnom 0
219 // send HoF
220 std::vector<IndividualP> myBest = this->at(0)->hof_->getBest();
221 state_->getCommunicator()->sendIndividualsGlobal(myBest, 0);
222 // send stats
223 std::vector<double> myStats = stats_->getStats();
224 state_->getCommunicator()->sendValuesGlobal(myStats, 0);
225 }
226 }
227}
228
229
233void Population::write(XMLNode &xPopulation)
234{
235 CommunicatorP comm = state_->getCommunicator();
236
237 // only deme masters continue
238 if(comm->getCommRank() != 0)
239 return;
240
241 xPopulation = XMLNode::createXMLTopNode(NODE_POPULATION);
242 xPopulation.addAttribute("size", uint2str(nDemes_).c_str());
243
244 XMLNode xHoF;
245 hof_->write(xHoF);
246 xPopulation.addChild(xHoF);
247
248 // write local deme
249 XMLNode xDeme;
250 this->at(0)->write(xDeme);
251 xPopulation.addChild(xDeme);
252
253 // collect remote demes
254 if(comm->getCommGlobalRank() == 0) {
255 for(uint iDeme = 1; iDeme < nDemes_; iDeme++) {
256 XMLNode xDeme;
257 voidP msg = comm->recvDataGlobal();
258 xDeme = XMLNode::parseString((char*) msg.get(), "Deme");
259 xPopulation.addChild(xDeme);
260 }
261 }
262 else {
263 char* message = xDeme.createXMLString();
264 comm->sendDataGlobal((voidP) message, (uint) strlen(message), 0);
265 }
266}
267
268
273void Population::read(XMLNode &xPopulation)
274{
275 CommunicatorP comm = state_->getCommunicator();
276
277 // only deme masters continue
278 if(comm->getCommRank() != 0)
279 return;
280
281 XMLNode xHof = xPopulation.getChildNode(0);
282 this->hof_->read(xHof);
283
284 // read the designated deme
285 XMLNode xDeme = xPopulation.getChildNode(getLocalDemeId() + 1);
286 getLocalDeme()->read(xDeme);
287}
288
289
290#endif // _MPI
Deme class - inherits a vector of Individual objects.
Definition: Deme.h:19
Records a set of best-so-far individuals.
Definition: HallOfFame.h:14
DemeP getLocalDeme()
get first deme (local deme in parallel ECF)
Definition: Population.h:35
void read(XMLNode &)
Read population from XMLNode (serial ECF). Population must be initialize()-d beforehand!
Definition: Population.cpp:65
uint myDemeIndex_
global index of local deme (at local process) - PECF only
Definition: Population.h:18
uint nDemes_
total number of demes in the population
Definition: Population.h:17
uint getLocalDemeId()
return local deme index (local process in parallel ECF)
Definition: Population.h:33
StatCalcP stats_
population statistics
Definition: Population.h:22
bool initialize(StateP state)
Initialize population (serial ECF).
Definition: Population.cpp:35
uint nIndividuals_
number of individuals (in each deme!)
Definition: Population.h:19
void write(XMLNode &)
Write population to XMLNode (serial ECF).
Definition: Population.cpp:80
void registerParameters(StateP state)
register population specific parameters
Definition: Population.cpp:16
void updateDemeStats()
Update, gather and write statistics of all demes; update and gather HallOfFame of all demes.
Definition: Population.cpp:100
HallOfFameP hof_
population HallOfFame
Definition: Population.h:21
Statistics calculation class.
Definition: StatCalc.h:20