ECF 1.5
Migration.cpp
1#include "ECF_base.h"
2#include "SelRandomOp.h"
3#include "SelBestOp.h"
4#include "SelWorstOp.h"
5
6#include "Migration.h"
7
8
10{
11 uint* freq = new uint(0);
12 state->getRegistry()->registerEntry("migration.freq", (voidP) freq, ECF::UINT,
13 "individuals are exchanged each 'freq' generations (default: none)");
14
15 uint* num = new uint(1);
16 state->getRegistry()->registerEntry("migration.number", (voidP) num, ECF::UINT,
17 "number of individuals to be sent to another deme (default: 1)");
18}
19
20
21bool Migration::initialize(StateP state)
22{
23 state_ = state;
24
25 voidP sptr = state->getRegistry()->getEntry("migration.freq");
26 migFrequency_ = *((uint*) sptr.get());
27
28 if(migFrequency_ == 0 && state->getPopulation()->getNoDemes() > 1) {
29 ECF_LOG_ERROR(state, "Warning: migration operator is not configured (migration will not occur between demes).");
30 }
31
32 if(migFrequency_ == 0)
33 return true;
34
35 sptr = state->getRegistry()->getEntry("migration.number");
36 nEmigrants_ = *((uint*) sptr.get());
37
38 if(nEmigrants_ >= state->getPopulation()->getLocalDeme()->getSize()) {
39 ECF_LOG_ERROR(state, "Error: number of emmigrants greater than deme size!");
40 throw "";
41 }
42
43 if(state->getPopulation()->getNoDemes() == 1) {
44 ECF_LOG_ERROR(state, "Warning: migration operator not applicable with a single deme population!");
45 migFrequency_ = 0;
46 }
47
48 selOp_.push_back(static_cast<SelectionOperatorP> (new SelBestOp));
49 selOp_.push_back(static_cast<SelectionOperatorP> (new SelRandomOp));
50
51 selOp_[BEST]->initialize(state);
52 selOp_[RANDOM]->initialize(state);
53
54 return true;
55}
56
57
58#ifndef _MPI
59
60bool Migration::operate(StateP state)
61{
62 if(migFrequency_ == 0 || state->getGenerationNo() % migFrequency_ != 0)
63 return true;
64
65 std::vector< std::vector<IndividualP> > outPool_, inPool_;
66 outPool_.resize(state->getPopulation()->getNoDemes());
67 inPool_.resize(state->getPopulation()->getNoDemes());
68
69 //
70 // emigrant selection: best + random
71 // emigrant no: 'nEmigrants' parameter
72 //
73 for(uint iDeme = 0; iDeme < state->getPopulation()->getNoDemes(); iDeme++) {
74
75 DemeP myDeme = state->getPopulation()->at(iDeme);
76 std::vector<IndividualP> emigrants;
77 IndividualP myBest = selOp_[BEST]->select(*myDeme);
78 emigrants.push_back(myBest);
79 for(uint i = 1; i < nEmigrants_; i++)
80 emigrants.push_back(selOp_[RANDOM]->select(*myDeme));
81
82 outPool_[iDeme] = emigrants;
83 }
84
85 // copy selected individuals
86 for(uint i = 0; i < outPool_.size(); i++)
87 for(uint j = 0; j < outPool_[i].size(); j++)
88 outPool_[i][j] = (IndividualP) outPool_[i][j]->copy();
89
90 //
91 // topology: ring
92 //
93 for(uint iDeme = 0; iDeme < state->getPopulation()->getNoDemes(); iDeme++) {
94
95 uint destDeme = (iDeme + 1) % state->getPopulation()->getNoDemes();
96 inPool_[destDeme] = outPool_[iDeme];
97 }
98
99 //
100 // replacement: random (protect the best)
101 //
102 for(uint iDeme = 0; iDeme < state->getPopulation()->getNoDemes(); iDeme++) {
103
104 DemeP myDeme = state->getPopulation()->at(iDeme);
105 IndividualP myBest = selOp_[BEST]->select(*myDeme);
106 std::vector<IndividualP> immigrants = inPool_[iDeme];
107 ECF_LOG(state, 4, "Received inds fitness: " + dbl2str(immigrants[0]->fitness->getValue()));
108
109 for(int i = (int) immigrants.size() - 1; i >= 0; i--) {
110 IndividualP victim;
111 do
112 victim = selOp_[RANDOM]->select(*myDeme);
113 while(victim == myBest);
114
115 state->getAlgorithm()->replaceWith(victim, immigrants[i]);
116 }
117 }
118
119 return true;
120}
121
122
123#else // _MPI
124
125bool Migration::operate(StateP state)
126{
127 if(migFrequency_ == 0 || state->getGenerationNo() % migFrequency_ != 0)
128 return true;
129
130 CommunicatorP comm = state->getCommunicator();
131
132 //
133 // emigrant selection: best + random
134 // emigrant no: 'nEmigrants' parameter
135 //
136 DemeP myDeme = state->getPopulation()->at(0);
137 std::vector<IndividualP> emigrants;
138 IndividualP myBest = selOp_[BEST]->select(*myDeme);
139 emigrants.push_back(myBest);
140 for(uint i = 1; i < nEmigrants_; i++)
141 emigrants.push_back(selOp_[RANDOM]->select(*myDeme));
142
143 //
144 // topology: ring
145 //
146 uint destDeme = (state->getPopulation()->getLocalDemeId() + 1) % state->getPopulation()->getNoDemes();
147 uint destProcess = comm->getDemeMaster(destDeme);
148 comm->sendIndividualsGlobal(emigrants, destProcess);
149
150 //
151 // replacement: random (protect the best)
152 //
153 std::vector<IndividualP> immigrants = comm->recvIndividualsGlobal();
154 ECF_LOG(state, 4, "Received inds fitness: " + dbl2str(immigrants[0]->fitness->getValue()));
155
156 for(int i = (int) immigrants.size() - 1; i >= 0; i--) {
157 IndividualP victim;
158 do
159 victim = selOp_[RANDOM]->select(*myDeme);
160 while(victim == myBest);
161
162 state->getAlgorithm()->replaceWith(victim, immigrants[i]);
163 }
164
165 return true;
166}
167
168#endif // _MPI
void registerParameters(StateP)
Register parameters with the Registry. Called before Operator::initialize.
Definition: Migration.cpp:9
bool initialize(StateP)
Perform initialization. Called before Operator::operate. By default, if the return value is false,...
Definition: Migration.cpp:21
bool operate(StateP)
Definition: Migration.cpp:60
Best individual selection operator.
Definition: SelBestOp.h:10
Random individual selection operator.
Definition: SelRandomOp.h:12