00001 #include "ECF_base.h"
00002 #include "SelRandomOp.h"
00003 #include "SelBestOp.h"
00004 #include "SelWorstOp.h"
00005
00006 #include "Migration.h"
00007
00008
00009 void Migration::registerParameters(StateP state)
00010 {
00011 uint* freq = new uint(0);
00012 state->getRegistry()->registerEntry("migration.freq", (voidP) freq, ECF::UINT,
00013 "individuals are exchanged each 'freq' generations (default: none)");
00014
00015 uint* num = new uint(1);
00016 state->getRegistry()->registerEntry("migration.number", (voidP) num, ECF::UINT,
00017 "number of individuals to be sent to another deme (default: 1)");
00018 }
00019
00020
00021 bool Migration::initialize(StateP state)
00022 {
00023 state_ = state;
00024
00025 voidP sptr = state->getRegistry()->getEntry("migration.freq");
00026 migFrequency_ = *((uint*) sptr.get());
00027
00028 if(migFrequency_ == 0 && state->getPopulation()->getNoDemes() > 1) {
00029 ECF_LOG_ERROR(state, "Warning: migration operator is not configured (migration will not occur between demes).");
00030 }
00031
00032 if(migFrequency_ == 0)
00033 return true;
00034
00035 sptr = state->getRegistry()->getEntry("migration.number");
00036 nEmigrants_ = *((uint*) sptr.get());
00037
00038 if(nEmigrants_ >= state->getPopulation()->getLocalDeme()->getSize()) {
00039 ECF_LOG_ERROR(state, "Error: number of emmigrants greater than deme size!");
00040 throw "";
00041 }
00042
00043 if(state->getPopulation()->getNoDemes() == 1) {
00044 ECF_LOG_ERROR(state, "Warning: migration operator not applicable with a single deme population!");
00045 migFrequency_ = 0;
00046 }
00047
00048 selOp_.push_back(static_cast<SelectionOperatorP> (new SelBestOp));
00049 selOp_.push_back(static_cast<SelectionOperatorP> (new SelRandomOp));
00050
00051 selOp_[BEST]->initialize(state);
00052 selOp_[RANDOM]->initialize(state);
00053
00054 return true;
00055 }
00056
00057
00058 #ifndef _MPI
00059
00060 bool Migration::operate(StateP state)
00061 {
00062 if(migFrequency_ == 0 || state->getGenerationNo() % migFrequency_ != 0)
00063 return true;
00064
00065 std::vector< std::vector<IndividualP> > outPool_, inPool_;
00066 outPool_.resize(state->getPopulation()->getNoDemes());
00067 inPool_.resize(state->getPopulation()->getNoDemes());
00068
00069
00070
00071
00072
00073 for(uint iDeme = 0; iDeme < state->getPopulation()->getNoDemes(); iDeme++) {
00074
00075 DemeP myDeme = state->getPopulation()->at(iDeme);
00076 std::vector<IndividualP> emigrants;
00077 IndividualP myBest = selOp_[BEST]->select(*myDeme);
00078 emigrants.push_back(myBest);
00079 for(uint i = 1; i < nEmigrants_; i++)
00080 emigrants.push_back(selOp_[RANDOM]->select(*myDeme));
00081
00082 outPool_[iDeme] = emigrants;
00083 }
00084
00085
00086 for(uint i = 0; i < outPool_.size(); i++)
00087 for(uint j = 0; j < outPool_[i].size(); j++)
00088 outPool_[i][j] = (IndividualP) outPool_[i][j]->copy();
00089
00090
00091
00092
00093 for(uint iDeme = 0; iDeme < state->getPopulation()->getNoDemes(); iDeme++) {
00094
00095 uint destDeme = (iDeme + 1) % state->getPopulation()->getNoDemes();
00096 inPool_[destDeme] = outPool_[iDeme];
00097 }
00098
00099
00100
00101
00102 for(uint iDeme = 0; iDeme < state->getPopulation()->getNoDemes(); iDeme++) {
00103
00104 DemeP myDeme = state->getPopulation()->at(iDeme);
00105 IndividualP myBest = selOp_[BEST]->select(*myDeme);
00106 std::vector<IndividualP> immigrants = inPool_[iDeme];
00107 ECF_LOG(state, 4, "Received inds fitness: " + dbl2str(immigrants[0]->fitness->getValue()));
00108
00109 for(int i = (int) immigrants.size() - 1; i >= 0; i--) {
00110 IndividualP victim;
00111 do
00112 victim = selOp_[RANDOM]->select(*myDeme);
00113 while(victim == myBest);
00114
00115 state->getAlgorithm()->replaceWith(victim, immigrants[i]);
00116 }
00117 }
00118
00119 return true;
00120 }
00121
00122
00123 #else // _MPI
00124
00125 bool Migration::operate(StateP state)
00126 {
00127 if(migFrequency_ == 0 || state->getGenerationNo() % migFrequency_ != 0)
00128 return true;
00129
00130 CommunicatorP comm = state->getCommunicator();
00131
00132
00133
00134
00135
00136 DemeP myDeme = state->getPopulation()->at(0);
00137 std::vector<IndividualP> emigrants;
00138 IndividualP myBest = selOp_[BEST]->select(*myDeme);
00139 emigrants.push_back(myBest);
00140 for(uint i = 1; i < nEmigrants_; i++)
00141 emigrants.push_back(selOp_[RANDOM]->select(*myDeme));
00142
00143
00144
00145
00146 uint destDeme = (state->getPopulation()->getLocalDemeId() + 1) % state->getPopulation()->getNoDemes();
00147 uint destProcess = comm->getDemeMaster(destDeme);
00148 comm->sendIndividualsGlobal(emigrants, destProcess);
00149
00150
00151
00152
00153 std::vector<IndividualP> immigrants = comm->recvIndividualsGlobal();
00154 ECF_LOG(state, 4, "Received inds fitness: " + dbl2str(immigrants[0]->fitness->getValue()));
00155
00156 for(int i = (int) immigrants.size() - 1; i >= 0; i--) {
00157 IndividualP victim;
00158 do
00159 victim = selOp_[RANDOM]->select(*myDeme);
00160 while(victim == myBest);
00161
00162 state->getAlgorithm()->replaceWith(victim, immigrants[i]);
00163 }
00164
00165 return true;
00166 }
00167
00168 #endif // _MPI