00001 #ifndef Algorithm_h
00002 #define Algorithm_h
00003
00004 #include "State.h"
00005 #include "SelectionOperator.h"
00006 #include "Crossover.h"
00007 #include "Mutation.h"
00008 #include "EvaluateOp.h"
00009 #include<vector>
00010
00019 class Algorithm
00020 {
00021 protected:
00022 DemeP activeDeme_;
00023 std::string name_;
00024 bool bImplicitParallel_;
00025 std::vector<SelectionOperatorP> selectionOp;
00026
00035 bool registerParameter(StateP state, std::string name, voidP value, enum ECF::type T, std::string description = "")
00036 {
00037 return state->getRegistry()->registerEntry(name_ + "." + name, value, T, description);
00038 }
00039
00046 voidP getParameterValue(StateP state, std::string name)
00047 {
00048 return state->getRegistry()->getEntry(name_ + "." + name);
00049 }
00050
00051 #ifdef _MPI
00052 std::vector<IndividualP> requests_, stored_;
00053 std::vector<uint> requestIds_;
00054 std::vector<IndividualP> demeCopy_;
00055 std::vector<IndividualP> myJob_;
00056 CommunicatorP comm_;
00057 uint jobSize_;
00058 uint totalEvaluations_, wastedEvaluations_;
00059 bool bImplicitEvaluation_;
00060 bool bImplicitMutation_;
00061 bool bSynchronized_;
00062 SelectionOperatorP selBestOp;
00063 std::vector<IndividualP> requestsMut_, receivedMut_;
00064 std::vector<uint> requestMutIds_;
00065 IndividualP currentBest_;
00066
00067 std::vector<IndividualP> storedInds_;
00068 std::vector< std::vector<IndividualP> > sentInds_;
00069 std::vector<bool> isConsistent_;
00070
00071 void storeIndividual(IndividualP);
00072 void storeGenotypes(std::vector<IndividualP>&);
00073 void setConsistency(IndividualP);
00074 void restoreIndividuals(std::vector<uint>);
00075 void restorePopulation();
00076 #endif
00077
00078
00079 public:
00080 CrossoverP crossover_;
00081 MutationP mutation_;
00082 EvaluateOpP evalOp_;
00083 StateP state_;
00084
00085 Algorithm()
00086 { bImplicitParallel_ = false; }
00087
00088 virtual ~Algorithm()
00089 { }
00090
00092 std::string getName()
00093 { return name_; }
00094
00096 virtual bool isParallel()
00097 { return false; }
00098
00100 bool isImplicitParallel()
00101 { return bImplicitParallel_; }
00102
00108 virtual bool advanceGeneration(StateP, DemeP) = 0;
00109
00115 virtual bool initialize(StateP)
00116 { return true; }
00117
00123 virtual void registerParameters(StateP) {}
00124
00128 virtual bool initializePopulation(StateP);
00129
00130 virtual void read() {}
00131
00132 #ifndef _MPI
00133
00139 virtual bool advanceGeneration(StateP state)
00140 {
00141 ECF_LOG(state, 4, name_ + ": starting generation");
00142
00143 bool bResult = true;
00144 for(uint iDeme = 0; iDeme < state->getPopulation()->size(); iDeme++) {
00145 activeDeme_ = state->getPopulation()->at(iDeme);
00146 bResult |= advanceGeneration(state, state->getPopulation()->at(iDeme));
00147 }
00148
00149 ECF_LOG(state, 4, name_ + ": ending generation");
00150
00151 return bResult;
00152 }
00153
00157 void evaluate(IndividualP ind)
00158 {
00159 state_->getContext()->evaluatedIndividual = ind;
00160 ECF_LOG(state_, 5, "Evaluating individual: " + ind->toString());
00161 ind->fitness = evalOp_->evaluate(ind);
00162 ECF_LOG(state_, 5, "New fitness: " + ind->fitness->toString());
00163 state_->increaseEvaluations();
00164 }
00165
00169 uint mutate(const std::vector<IndividualP>& pool)
00170 { return mutation_->mutation(pool); }
00171
00175 uint mutate(const IndividualP victim)
00176 {
00177 std::vector<IndividualP> pool;
00178 pool.push_back(victim);
00179 return mutation_->mutation(pool);
00180 }
00181
00187 void replaceWith(IndividualP oldInd, IndividualP newInd)
00188 { activeDeme_->replace(oldInd->index, newInd); }
00189
00195 void replaceWith(uint oldIndId, IndividualP newInd)
00196 { activeDeme_->replace(oldIndId, newInd); }
00197
00199 void registerParallelParameters(StateP state)
00200 { }
00201
00203 bool initializeParallel(StateP state)
00204 { return true; }
00205
00206 #else // implicit parallel version
00207
00209 virtual bool advanceGeneration(StateP state);
00210
00212 virtual void bcastTermination(StateP state);
00213
00215 void registerParallelParameters(StateP state);
00216
00218 bool initializeParallel(StateP state);
00219
00221 void initializeImplicit(StateP state);
00222
00224 bool implicitParallelOperate(StateP state);
00225
00227 void evaluate(IndividualP ind)
00228 {
00229
00230 if(bImplicitEvaluation_)
00231 implicitEvaluate(ind);
00232
00233 else if(bImplicitMutation_ && ind->fitness->isValid())
00234 return;
00235
00236 state_->getContext()->evaluatedIndividual = ind;
00237 ECF_LOG(state_, 5, "Evaluating individual: " + ind->toString());
00238 ind->fitness = evalOp_->evaluate(ind);
00239 ECF_LOG(state_, 5, "New fitness: " + ind->fitness->toString());
00240 state_->increaseEvaluations();
00241 }
00242
00244 void implicitEvaluate(IndividualP ind);
00245
00247 uint mutate(const IndividualP victim)
00248 {
00249 std::vector<IndividualP> pool;
00250 pool.push_back(victim);
00251 return mutate(pool);
00252 }
00253
00255 uint mutate(const std::vector<IndividualP>& pool)
00256 {
00257 if(bImplicitMutation_) {
00258 uint nMutations = 0;
00259 for(uint i = 0; i < pool.size(); i++) {
00260 nMutations += implicitMutate(pool[i]);
00261 }
00262 return nMutations;
00263 }
00264 else
00265 return mutation_->mutation(pool);
00266 }
00267
00269 uint implicitMutate(IndividualP ind);
00270
00272 void replaceWith(IndividualP oldInd, IndividualP newInd);
00273
00275 void replaceWith(uint oldIndId, IndividualP newInd)
00276 { replaceWith(state_->getPopulation()->getLocalDeme()->at(oldIndId), newInd); }
00277
00278 #endif
00279
00280
00281
00285 bool mate(IndividualP p1, IndividualP p2, IndividualP child)
00286 { return crossover_->mate(p1, p2, child); }
00287
00291 IndividualP copy(IndividualP source)
00292 { return (IndividualP) source->copy(); }
00293
00297 bool removeFrom(IndividualP victim, std::vector<IndividualP> &pool)
00298 {
00299 uint iWorst = 0;
00300 while(iWorst < pool.size() && pool[iWorst] != victim)
00301 iWorst++;
00302 if(iWorst == pool.size())
00303 return false;
00304 pool.erase(pool.begin() + iWorst);
00305 return true;
00306 }
00307
00311 bool isMember(IndividualP single, std::vector<IndividualP> &pool)
00312 {
00313 uint index = 0;
00314 while(index < pool.size() && pool[index] != single)
00315 index++;
00316 if(index == pool.size())
00317 return false;
00318 return true;
00319 }
00320 };
00321 typedef boost::shared_ptr<Algorithm> AlgorithmP;
00322
00323 #endif // Algorithm_h
00324