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