00001 #include "ECF.h"
00002 #include <fstream>
00003 #include <iomanip>
00004 #include <time.h>
00005
00006
00012 State::State()
00013 {
00014 this->population_ = static_cast<PopulationP> (new Population);
00015 this->crossover_ = static_cast<CrossoverP> (new Crossover);
00016 this->mutation_ = static_cast<MutationP> (new Mutation);
00017
00018 XMLNode::setGlobalOptions(XMLNode::char_encoding_legacy);
00019
00020 bInitialized_ = false;
00021 bAlgorithmSet_ = false;
00022 bGenotypeSet_ = false;
00023 bEvaluatorSet_ = false;
00024 bLoadMilestone_ = false;
00025 bBatchMode_ = false;
00026 bBatchStart_ = false;
00027 bBatchSingleMilestone_ = false;
00028 bBatchWriteStats_ = false;
00029
00030
00031
00032 AlgorithmP alg = static_cast<AlgorithmP> (new SteadyStateTournament);
00033 this->mAlgorithms_[alg->getName()] = alg;
00034 alg = static_cast<AlgorithmP> (new RouletteWheel);
00035 this->mAlgorithms_[alg->getName()] = alg;
00036 alg = static_cast<AlgorithmP> (new ParticleSwarmOptimization);
00037 this->mAlgorithms_[alg->getName()] = alg;
00038 alg = static_cast<AlgorithmP> (new Elimination);
00039 this->mAlgorithms_[alg->getName()] = alg;
00040
00041 #ifdef _MPI
00042
00043 alg = static_cast<AlgorithmP> (new AlgSGenGpea);
00044 this->mAlgorithms_[alg->getName()] = alg;
00045 alg = static_cast<AlgorithmP> (new AlgAEliGpea);
00046 this->mAlgorithms_[alg->getName()] = alg;
00047 alg = static_cast<AlgorithmP> (new AlgAEliGpea2);
00048 this->mAlgorithms_[alg->getName()] = alg;
00049 #endif
00050
00051
00052 GenotypeP gen = static_cast<GenotypeP> (new BitString::BitString);
00053 this->mGenotypes_[gen->getName()] = gen;
00054 gen = static_cast<GenotypeP> (new Binary::Binary);
00055 this->mGenotypes_[gen->getName()] = gen;
00056 gen = static_cast<GenotypeP> (new Tree::Tree);
00057 this->mGenotypes_[gen->getName()] = gen;
00058 gen = static_cast<GenotypeP> (new Permutation::Permutation);
00059 this->mGenotypes_[gen->getName()] = gen;
00060 gen = static_cast<GenotypeP> (new FloatingPoint::FloatingPoint);
00061 this->mGenotypes_[gen->getName()] = gen;
00062
00063
00064 OperatorP op = static_cast<OperatorP> (new TermStagnationOp);
00065 this->allTerminationOps_.push_back(op);
00066 op = static_cast<OperatorP> (new TermMaxGenOp);
00067 this->allTerminationOps_.push_back(op);
00068 op = static_cast<OperatorP> (new TermFitnessValOp);
00069 this->allTerminationOps_.push_back(op);
00070 op = static_cast<OperatorP> (new TermMaxTimeOp);
00071 this->allTerminationOps_.push_back(op);
00072
00073 setRandomizer(static_cast<RandomizerP> (new SimpleRandomizer));
00074 this->registry_ = static_cast<RegistryP> (new Registry);
00075 this->logger_ = static_cast<LoggerP> (new Logger);
00076 this->statistic_ = static_cast<StatCalcP> (new StatCalc);
00077 this->comm_ = static_cast<CommunicatorP> (new Comm::Communicator);
00078 this->migration_ = static_cast<MigrationP> (new Migration);
00079 }
00080
00081
00086 void State::registerParameters()
00087 {
00088
00089 registry_->registerEntry("milestone.interval", (voidP) (new uint(0)), ECF::UINT);
00090 registry_->registerEntry("milestone.filename", (voidP) (new std::string("milestone.txt")), ECF::STRING);
00091 registry_->registerEntry("batch.repeats", (voidP) (new uint(0)), ECF::UINT);
00092 registry_->registerEntry("batch.singlemilestone", (voidP) (new uint(0)), ECF::UINT);
00093 registry_->registerEntry("batch.statsfile", (voidP) (new std::string("")), ECF::STRING);
00094
00095
00096 registry_->registerEntry("milestone.generation_", (voidP) (new uint(0)), ECF::UINT);
00097 registry_->registerEntry("milestone.elapsedtime_", (voidP) (new uint(0)), ECF::UINT);
00098 registry_->registerEntry("batch.remaining_", (voidP) (new uint(0)), ECF::UINT);
00099 registry_->registerEntry("batch.logfile_", (voidP) (new std::string("")), ECF::STRING);
00100
00101
00102 alg_iter itAlg;
00103 for(itAlg = mAlgorithms_.begin(); itAlg != mAlgorithms_.end(); itAlg++)
00104 itAlg->second->registerParameters(state_);
00105
00106
00107 mAlgorithms_.begin()->second->registerParallelParameters(state_);
00108
00109 for(uint i = 0; i < allTerminationOps_.size(); i++)
00110 allTerminationOps_[i]->registerParameters(state_);
00111
00112
00113 for(uint i = 0; i < allUserOps_.size(); i++)
00114 allUserOps_[i]->registerParameters(state_);
00115
00116 mutation_->registerParameters(state_);
00117 crossover_->registerParameters(state_);
00118 randomizer_->registerParameters(state_);
00119 population_->registerParameters(state_);
00120 logger_->registerParameters(state_);
00121 migration_->registerParameters(state_);
00122 evalOp_->registerParameters(state_);
00123 }
00124
00125
00130 void State::readParameters()
00131 {
00132
00133 if(registry_->isModified("milestone.filename"))
00134 bSaveMilestone_ = true;
00135 else
00136 bSaveMilestone_ = false;
00137
00138 voidP sptr = registry_->getEntry("milestone.interval");
00139 milestoneInterval_ = *((uint*) sptr.get());
00140
00141 sptr = registry_->getEntry("milestone.filename");
00142 milestoneFilename_ = *((std::string*) sptr.get());
00143
00144
00145 if(registry_->isModified("milestone.generation_"))
00146 bLoadMilestone_ = true;
00147 else
00148 bLoadMilestone_ = false;
00149
00150 sptr = registry_->getEntry("milestone.generation_");
00151 milestoneGeneration_ = *((uint*) sptr.get());
00152
00153 sptr = registry_->getEntry("milestone.elapsedtime_");
00154 milestoneElapsedTime_ = *((uint*) sptr.get());
00155
00156
00157 sptr = registry_->getEntry("batch.repeats");
00158 batchRepeats_ = *((uint*) sptr.get());
00159
00160 sptr = registry_->getEntry("batch.remaining_");
00161 batchRemaining_ = *((uint*) sptr.get());
00162
00163 sptr = registry_->getEntry("batch.statsfile");
00164 batchStatsFile_ = *((std::string*) sptr.get());
00165
00166 sptr = registry_->getEntry("batch.logfile_");
00167 batchLogFile_ = *((std::string*) sptr.get());
00168
00169 sptr = registry_->getEntry("batch.singlemilestone");
00170 bBatchSingleMilestone_ = *((uint*) sptr.get()) % 2 ? true:false;
00171
00172 if(registry_->isModified("batch.repeats") && batchRepeats_ > 1)
00173 bBatchStart_ = true;
00174 else
00175 bBatchStart_ = false;
00176 }
00177
00178
00184 bool State::parseConfig(std::string filename)
00185 {
00186 std::ifstream fin(filename.c_str());
00187 if (!fin) {
00188 throw std::string("Error opening file " + filename);
00189 }
00190 std::cout << "Parsing configuration file: " << filename << std::endl;
00191
00192 std::string xmlFile, temp;
00193 while (!fin.eof())
00194 getline(fin, temp), xmlFile += "\n" + temp;
00195
00196 XMLResults results;
00197 xConfig_ = XMLNode::parseString(xmlFile.c_str(), "ECF", &results);
00198 if (results.error != eXMLErrorNone) {
00199 std::cerr << "Configuration file: " << XMLNode::getError(results.error);
00200 std::cerr << " (line " << results.nLine << ", col " << results.nColumn << ")" << std::endl;
00201 throw("");
00202 }
00203
00204 if (xConfig_.isEmpty())
00205 return false;
00206
00207 int n = xConfig_.nChildNode();
00208 for (int i = 0; i < n; ++i) {
00209 XMLNode child = xConfig_.getChildNode(i);
00210 std::string name = child.getName();
00211 bool ok = true;
00212
00213 if (name == NODE_REGISTRY)
00214 ok &= registry_->readEntries(child);
00215 else if (name == NODE_ALGORITHM)
00216 ok &= parseAlgorithmNode(child);
00217 else if (name == NODE_GENOTYPE)
00218 ok &= parseGenotypeNode(child);
00219 else if (name == NODE_POPULATION)
00220 continue;
00221 else
00222 std::cerr << "Unknown node: " << name << std::endl;
00223
00224 if (!ok)
00225 throw "";
00226 }
00227
00228 return true;
00229 }
00230
00231
00237 bool State::parseAlgorithmNode(XMLNode node)
00238 {
00239 int n = node.nChildNode();
00240 if (n > 1)
00241 std::cerr << "Warning: multiple Algorithm nodes found! (using the first one)" << std::endl;
00242
00243 XMLNode child = node.getChildNode(0);
00244 alg_iter alg = mAlgorithms_.find(child.getName());
00245 if (alg == mAlgorithms_.end()) {
00246 throw std::string("Error: unknown Algorithm : ") + child.getName();
00247 }
00248
00249 algorithm_ = alg->second;
00250 bAlgorithmSet_ = true;
00251
00252 if (! registry_->readEntries(child, child.getName()))
00253 return false;
00254
00255 return true;
00256 }
00257
00258
00264 bool State::parseGenotypeNode(XMLNode node)
00265 {
00266 int n = node.nChildNode();
00267 for (int i = 0; i < n; ++i) {
00268 XMLNode child = node.getChildNode(i);
00269 gen_iter gen = mGenotypes_.find(child.getName());
00270 if (gen == mGenotypes_.end()) {
00271 throw std::string("Error: unknown Genotype : ") + child.getName();
00272 }
00273
00274 uint genotypeId = (uint) genotype_.size();
00275 gen->second->setGenotypeId(genotypeId);
00276 gen->second->registerParameters(state_);
00277 setGenotype(gen->second);
00278
00279 if (! registry_->readEntries(child, child.getName(), genotypeId))
00280 return false;
00281 }
00282
00283 return true;
00284 }
00285
00286
00293 bool State::initializeComponents(int argc, char **argv)
00294 {
00295 try {
00296 bTerminate_ = false;
00297 generationNo_ = 0;
00298
00299 logger_->initialize(state_);
00300 randomizer_->initialize(state_);
00301
00302
00303 for(uint i = 0; i < genotype_.size(); i++) {
00304 GenotypeP copy = (GenotypeP) genotype_[i]->copy();
00305 bInitialized_ &= copy->initialize(state_);
00306 }
00307 if(!bInitialized_) {
00308 throw "Error: Genotype initialization failed!";
00309 }
00310
00311
00312 bInitialized_ &= comm_->initialize(state_, argc, argv);
00313
00314
00315 algorithm_->evalOp_ = this->evalOp_;
00316 algorithm_->crossover_ = crossover_;
00317 algorithm_->mutation_ = mutation_;
00318 algorithm_->initialize(state_);
00319
00320 population_->initialize(state_);
00321 algorithm_->initializeParallel(state_);
00322
00323 mutation_->initialize(state_);
00324 crossover_->initialize(state_);
00325 migration_->initialize(state_);
00326
00327
00328 activeTerminationOps_.clear();
00329 for(uint i = 0; i < allTerminationOps_.size(); i++)
00330 if(allTerminationOps_[i]->initialize(state_))
00331 activeTerminationOps_.push_back(allTerminationOps_[i]);
00332
00333 if(activeTerminationOps_.size() == 0)
00334 activeTerminationOps_.push_back(allTerminationOps_[0]);
00335
00336
00337 activeUserOps_.clear();
00338 for(uint i = 0; i < allUserOps_.size(); i++)
00339 if(allUserOps_[i]->initialize(state_))
00340 activeUserOps_.push_back(allUserOps_[i]);
00341
00342
00343 if(!evalOp_->initialize(state_))
00344 throw "Error: Evaluation operator initialization failed!";
00345
00346
00347 individual_ = (IndividualP) (new Individual(state_));
00348 fitness_ = evalOp_->evaluate(individual_);
00349
00350 }
00351
00352 catch(std::string& msg) {
00353 std::cerr << msg << std::endl;
00354 bInitialized_ = false;
00355 }
00356 catch(const char* msg) {
00357 std::cerr << msg << std::endl;
00358 bInitialized_ = false;
00359 }
00360 catch(...) {
00361 std::cerr << "Unknown error in initialization!" << std::endl;
00362 bInitialized_ = false;
00363 }
00364
00365 return bInitialized_;
00366 }
00367
00368
00375 bool State::runBatch()
00376 {
00377 bBatchStart_ = false;
00378 bBatchMode_ = true;
00379
00380 bool bUseLog = registry_->isModified("log.filename");
00381
00382 if(!bLoadMilestone_)
00383 batchRemaining_ = batchRepeats_;
00384 uint numerals = 1 + (uint) (log((double) batchRepeats_) / log((double) 10.));
00385
00386
00387 std::string logFileName = *(std::string*) registry_->getEntry("log.filename").get();
00388 std::string logFileExt = "";
00389 if(bLoadMilestone_)
00390 logFileName = batchLogFile_;
00391 else
00392 batchLogFile_ = logFileName;
00393
00394 if(logFileName.find(".") != std::string::npos) {
00395 logFileExt = logFileName.substr(logFileName.find("."));
00396 logFileName = logFileName.substr(0, logFileName.find("."));
00397 }
00398
00399
00400 std::string milestoneName = *(std::string*) registry_->getEntry("milestone.filename").get();
00401 std::string milestoneExt = "";
00402 if(milestoneName.find(".") != std::string::npos) {
00403 milestoneExt = milestoneName.substr(milestoneName.find("."));
00404 milestoneName = milestoneName.substr(0, milestoneName.find("."));
00405 }
00406
00407
00408 std::ofstream statsFile;
00409 if(registry_->isModified("batch.statsfile")) {
00410 if(bLoadMilestone_)
00411 statsFile.open(batchStatsFile_.c_str(), std::ios_base::app);
00412 else {
00413 statsFile.open(batchStatsFile_.c_str());
00414 statsFile << "runId\tfit_min\tfit_max\tfit_avg\tfit_std\n";
00415 }
00416 if(!statsFile) {
00417 logger_->log(1, "Error: can't open batch statsfile (" + batchStatsFile_ + ")!");
00418 return false;
00419 }
00420 statsFile.close();
00421 bBatchWriteStats_ = true;
00422 }
00423
00424 uint runId = batchRepeats_ - batchRemaining_ + 1;
00425
00426 for(; runId <= batchRepeats_; runId++) {
00427
00428 if(bUseLog) {
00429 std::stringstream ss;
00430 ss << std::setw(numerals) << std::setfill('0') << runId;
00431 std::string currentLogName = logFileName + "_" + ss.str() + logFileExt;
00432 registry_->modifyEntry("log.filename", (voidP) new std::string(currentLogName));
00433 }
00434
00435
00436 if(!bBatchSingleMilestone_) {
00437 std::stringstream ss;
00438 ss << std::setw(numerals) << std::setfill('0') << runId;
00439 milestoneFilename_ = milestoneName + "_" + ss.str() + milestoneExt;
00440 }
00441
00442
00443 batchRemaining_--;
00444 bInitialized_ = true;
00445 initializeComponents(argc_, argv_);
00446 logger_->log(1, "Running in batch mode: run " + uint2str(runId) + "/" + uint2str(batchRepeats_));
00447 run();
00448
00449
00450 if(comm_->getCommGlobalRank() == 0) {
00451 if(bBatchWriteStats_) {
00452 statsFile.open(batchStatsFile_.c_str(), std::ios_base::app);
00453 std::vector<double> stats = population_->stats_->getStats();
00454 statsFile << runId << '\t';
00455 statsFile << stats[0] << '\t' << stats[1] << '\t' << stats[2] << '\t' << stats[3] << '\n';
00456 statsFile.close();
00457 }
00458 }
00459 }
00460
00461
00462 bBatchMode_ = false;
00463 comm_->finalize();
00464
00465 std::cout << "Batch mode end (" << batchRepeats_ << " runs concluded)." << std::endl;
00466
00467 if(statsFile)
00468 statsFile.close();
00469 return true;
00470 }
00471
00472
00483 bool State::initialize(int argc, char **argv)
00484 {
00485 this->state_ = this->getState();
00486 genotype_.clear();
00487 mutation_->operators.clear();
00488 crossover_->operators.clear();
00489
00490 bInitialized_ = true;
00491 argc_ = argc;
00492 argv_ = argv;
00493
00494 try {
00495
00496 std::cout << "-- ECF, version " << ECF_VERSION << " --" << std::endl;
00497
00498 if(!bEvaluatorSet_) {
00499 throw "Error: no EvaluateOp defined!";
00500 }
00501
00502
00503 std::string config_file;
00504 if (argc > 1)
00505 config_file = argv[1];
00506
00507 registerParameters();
00508
00509 if (config_file != "") {
00510 bInitialized_ = parseConfig(config_file);
00511 }
00512 else {
00513 std::cout << "Warning: no configuration file given." << std::endl;
00514 std::cout << "Example usage: <ECF_binary> <parameter_file>" << std::endl;
00515 }
00516
00517
00518 if (!bAlgorithmSet_)
00519 algorithm_ = mAlgorithms_.find("SteadyStateTournament")->second;
00520
00521 if(!bGenotypeSet_) {
00522 throw "Error: no Genotype defined!";
00523 }
00524
00525 readParameters();
00526
00527 if(bBatchStart_)
00528 return true;
00529
00530 initializeComponents(argc, argv);
00531
00532 if(bLoadMilestone_)
00533 loadMilestone();
00534
00535 }
00536
00537 catch(std::string& msg) {
00538 std::cerr << msg << std::endl;
00539 bInitialized_ = false;
00540 }
00541 catch(const char* msg) {
00542 std::cerr << msg << std::endl;
00543 bInitialized_ = false;
00544 }
00545 catch(...) {
00546 std::cerr << "Unknown error in initialization!" << std::endl;
00547 bInitialized_ = false;
00548 }
00549
00550 return bInitialized_;
00551 }
00552
00553
00557 bool State::isImplicitParallel()
00558 { return algorithm_->isImplicitParallel(); }
00559
00560
00564 bool State::isAlgorithmParallel()
00565 { return algorithm_->isParallel(); }
00566
00567
00572 void State::write(XMLNode& xState)
00573 {
00574 registry_->modifyEntry("milestone.generation_", (voidP) (new uint(getGenerationNo())));
00575 registry_->modifyEntry("milestone.elapsedtime_", (voidP) (new time_t(elapsedTime_)));
00576 registry_->modifyEntry("batch.remaining_", (voidP) (new uint(batchRemaining_)));
00577 if(registry_->isModified("log.filename"))
00578 registry_->modifyEntry("batch.logfile_", (voidP) (new std::string(batchLogFile_)));
00579 }
00580
00581
00586 void State::saveMilestone()
00587 {
00588 XMLNode xMainNode = XMLNode::createXMLTopNode("ECF");
00589 xMainNode.addAttribute("milestone", ctime(¤tTime_));
00590
00591 XMLNode xMilestone;
00592 this->write(xMilestone);
00593 xMainNode.addChild(xMilestone);
00594
00595 XMLNode xNode = this->xConfig_.getChildNode(NODE_ALGORITHM);
00596 xNode = xNode.deepCopy();
00597 xMainNode.addChild(xNode);
00598 xNode = this->xConfig_.getChildNode(NODE_GENOTYPE);
00599 xNode = xNode.deepCopy();
00600 xMainNode.addChild(xNode);
00601
00602 this->registry_->write(xNode);
00603 xMainNode.addChild(xNode);
00604
00605
00606 XMLNode xPopulation;
00607 population_->write(xPopulation);
00608 xMainNode.addChild(xPopulation);
00609
00610 #ifdef _MPI
00611 if(comm_->getCommGlobalRank() != 0)
00612 return;
00613 #endif
00614
00615 xMainNode.writeToFile(milestoneFilename_.c_str());
00616 }
00617
00618
00623 void State::loadMilestone()
00624 {
00625 XMLNode xPopulation = xConfig_.getChildNode("Population");
00626 population_->read(xPopulation);
00627
00628 generationNo_ = milestoneGeneration_;
00629 }
00630
00631
00632
00633
00634
00635
00636
00646 uint State::setGenotype(GenotypeP genotype)
00647 {
00648 genotype_.push_back((GenotypeP) genotype->copy());
00649 uint index = (uint) genotype_.size() - 1;
00650 genotype_[index]->setGenotypeId(index);
00651 genotype->setGenotypeId(index);
00652
00653 genotype_[index]->registerParameters(state_);
00654
00655
00656 crossover_->operators.push_back(genotype_[index]->getCrossoverOp());
00657 for(uint iOp = 0; iOp < crossover_->operators[index].size(); iOp++) {
00658 crossover_->operators[index][iOp]->myGenotype_ = genotype_[index];
00659 crossover_->operators[index][iOp]->registerParameters(state_);
00660 }
00661
00662 mutation_->operators.push_back(genotype_[index]->getMutationOp());
00663 for(uint iOp = 0; iOp < mutation_->operators[index].size(); iOp++) {
00664 mutation_->operators[index][iOp]->myGenotype_ = genotype_[index];
00665 mutation_->operators[index][iOp]->registerParameters(state_);
00666 }
00667
00668 bGenotypeSet_ = true;
00669 return index;
00670 }
00671
00672
00673 void State::setAlgorithm(AlgorithmP algorithm)
00674 {
00675 algorithm_ = algorithm;
00676 bAlgorithmSet_ = true;
00677 }
00678
00679
00685 void State::setEvalOp(EvaluateOpP eval)
00686 {
00687 evalOp_ = eval;
00688 bEvaluatorSet_ = true;
00689 }
00690
00691
00692
00693
00694
00695
00696
00705 bool State::addGenotype(GenotypeP gen)
00706 {
00707 mGenotypes_[gen->getName()] = gen;
00708 return true;
00709 }
00710
00711
00720 bool State::addAlgorithm(AlgorithmP alg)
00721 {
00722 mAlgorithms_[alg->getName()] = alg;
00723 return true;
00724 }
00725
00733 bool State::addOperator(OperatorP op)
00734 {
00735 allUserOps_.push_back(op);
00736 return true;
00737 }
00738
00739
00740
00741
00742
00743
00744
00745 #ifndef _MPI
00746
00752 bool State::run()
00753 {
00754 if(!bInitialized_) {
00755 std::cerr << "Error: Initialization failed!" << std::endl;
00756 return false;
00757 }
00758
00759 if(bBatchStart_) {
00760 runBatch();
00761 return true;
00762 }
00763
00764 startTime_ = time(NULL);
00765 std::string stime = ctime(&startTime_);
00766 logger_->log(3, "Start time: " + stime);
00767
00768 startTime_ -= milestoneElapsedTime_;
00769
00770
00771 logger_->log(2, "Evaluating initial population...");
00772 algorithm_->initializePopulation(state_);
00773
00774 currentTime_ = time(NULL);
00775 elapsedTime_ = currentTime_ - startTime_;
00776 logger_->log(2, "Generation: " + uint2str(generationNo_));
00777 logger_->log(2, "Elapsed time: " + uint2str((uint) elapsedTime_));
00778 population_->updateDemeStats();
00779
00780 for(uint i = 0; i < activeTerminationOps_.size(); i++)
00781 activeTerminationOps_[i]->operate(state_);
00782
00783
00784 while(bTerminate_ == false) {
00785 algorithm_->advanceGeneration(state_);
00786 generationNo_++;
00787
00788 currentTime_ = time(NULL);
00789 elapsedTime_ = currentTime_ - startTime_;
00790 logger_->log(2, "Generation: " + uint2str(generationNo_));
00791 logger_->log(2, "Elapsed time: " + uint2str((uint) elapsedTime_));
00792
00793 population_->updateDemeStats();
00794
00795
00796 for(uint i = 0; i < activeUserOps_.size(); i++)
00797 activeUserOps_[i]->operate(state_);
00798
00799
00800 for(uint i = 0; i < activeTerminationOps_.size(); i++)
00801 activeTerminationOps_[i]->operate(state_);
00802
00803 logger_->saveTo();
00804
00805 if(bSaveMilestone_ &&
00806 milestoneInterval_ > 0 && generationNo_ % milestoneInterval_ == 0)
00807 saveMilestone();
00808
00809 migration_->operate(state_);
00810 }
00811
00812
00813 XMLNode xHoF;
00814 population_->hof_->write(xHoF);
00815 char *out = xHoF.createXMLString(true);
00816 logger_->log(1, "\nBest of run: \n" + std::string(out));
00817 freeXMLString(out);
00818
00819
00820 logger_->saveTo(true);
00821 if(bSaveMilestone_)
00822 saveMilestone();
00823
00824 logger_->closeLog();
00825
00826 return true;
00827 }
00828
00829
00830 #else // _MPI
00831
00837 bool State::run()
00838 {
00839 if(bBatchStart_) {
00840 runBatch();
00841 return true;
00842 }
00843
00844
00845 if(!bInitialized_) {
00846 std::cerr << "Error: Initialization failed!" << std::endl;
00847 logger_->saveTo();
00848 if(comm_->isInitialized())
00849 comm_->finalize();
00850 return false;
00851 }
00852
00853 startTime_ = time(NULL);
00854 std::string stime = ctime(&startTime_);
00855 logger_->log(3, "Start time: " + stime);
00856
00857 startTime_ -= milestoneElapsedTime_;
00858
00859
00860
00861
00862 if(comm_->getCommRank() == 0) {
00863 logger_->log(2, "Evaluating initial population...");
00864 }
00865
00866
00867 algorithm_->initializePopulation(state_);
00868 comm_->synchronize();
00869
00870 currentTime_ = time(NULL);
00871 elapsedTime_ = currentTime_ - startTime_;
00872
00873 if(comm_->getCommRank() == 0) {
00874
00875 if(isImplicitParallel())
00876 algorithm_->initializeImplicit(state_);
00877
00878 logger_->log(2, "Generation: " + uint2str(generationNo_));
00879 logger_->log(2, "Elapsed time: " + uint2str((uint) elapsedTime_));
00880 population_->updateDemeStats();
00881 }
00882
00883 for(uint i = 0; i < activeTerminationOps_.size(); i++)
00884 activeTerminationOps_[i]->operate(state_);
00885
00886
00887 while(bTerminate_ == false) {
00888 algorithm_->advanceGeneration(state_);
00889
00890 generationNo_++;
00891 currentTime_ = time(NULL);
00892 elapsedTime_ = currentTime_ - startTime_;
00893 if(comm_->getCommGlobalRank() == 0) {
00894 logger_->log(2, "Generation: " + uint2str(generationNo_));
00895 logger_->log(2, "Elapsed time: " + uint2str((uint) elapsedTime_));
00896 }
00897
00898
00899 if(comm_->getCommRank() == 0) {
00900 population_->updateDemeStats();
00901
00902 if(bSaveMilestone_ && milestoneInterval_ > 0 && generationNo_ % milestoneInterval_ == 0)
00903 saveMilestone();
00904 }
00905
00906
00907 if(comm_->getCommGlobalRank() == 0) {
00908 for(uint i = 0; i < activeTerminationOps_.size(); i++)
00909 activeTerminationOps_[i]->operate(state_);
00910
00911 for(uint i = 1; i < population_->getNoDemes(); i++)
00912 comm_->sendTerminateMessage(comm_->getDemeMaster(i), bTerminate_);
00913 }
00914
00915 else if(comm_->getCommRank() == 0)
00916 bTerminate_ = comm_->recvTerminateMessage(0);
00917
00918
00919 algorithm_->bcastTermination(state_);
00920
00921
00922 if(comm_->getCommRank() == 0) {
00923 migration_->operate(state_);
00924 }
00925
00926
00927 for(uint i = 0; i < activeUserOps_.size(); i++)
00928 activeUserOps_[i]->operate(state_);
00929
00930 logger_->saveTo();
00931 }
00932
00933 logger_->setLogFrequency(1);
00934 if(comm_->getCommGlobalRank() == 0) {
00935
00936 XMLNode xHoF;
00937 population_->hof_->write(xHoF);
00938 std::string out = xHoF.createXMLString(true);
00939 logger_->log(1, "\nBest of run: \n" + out);
00940
00941 logger_->saveTo(true);
00942 }
00943
00944 if(comm_->getCommRank() == 0 && bSaveMilestone_)
00945 saveMilestone();
00946
00947 logger_->saveTo(true);
00948
00949
00950 comm_->finalize();
00951
00952 return true;
00953 }
00954 #endif // _MPI