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 this->context_ = static_cast<EvolutionContextP> (new EvolutionContext);
00018
00019 XMLNode::setGlobalOptions(XMLNode::char_encoding_legacy);
00020
00021 bInitialized_ = false;
00022 bAlgorithmSet_ = false;
00023 bGenotypeSet_ = false;
00024 bEvaluatorSet_ = false;
00025 bLoadMilestone_ = false;
00026 bBatchMode_ = false;
00027 bBatchStart_ = false;
00028 bBatchSingleMilestone_ = false;
00029 bBatchWriteStats_ = false;
00030
00031
00032
00033 AlgorithmP alg = static_cast<AlgorithmP> (new SteadyStateTournament);
00034 this->mAlgorithms_[alg->getName()] = alg;
00035 alg = static_cast<AlgorithmP> (new RouletteWheel);
00036 this->mAlgorithms_[alg->getName()] = alg;
00037 alg = static_cast<AlgorithmP> (new ParticleSwarmOptimization);
00038 this->mAlgorithms_[alg->getName()] = alg;
00039 alg = static_cast<AlgorithmP> (new Elimination);
00040 this->mAlgorithms_[alg->getName()] = alg;
00041 alg = static_cast<AlgorithmP> (new XCS);
00042 this->mAlgorithms_[alg->getName()] = alg;
00043 alg = static_cast<AlgorithmP> (new RandomSearch);
00044 this->mAlgorithms_[alg->getName()] = alg;
00045 alg = static_cast<AlgorithmP> (new GeneticAnnealing);
00046 this->mAlgorithms_[alg->getName()] = alg;
00047 alg = static_cast<AlgorithmP> (new DifferentialEvolution);
00048 this->mAlgorithms_[alg->getName()] = alg;
00049
00050 #ifdef _MPI
00051
00052 alg = static_cast<AlgorithmP> (new AlgSGenGpea);
00053 this->mAlgorithms_[alg->getName()] = alg;
00054 alg = static_cast<AlgorithmP> (new AlgAEliGpea);
00055 this->mAlgorithms_[alg->getName()] = alg;
00056 alg = static_cast<AlgorithmP> (new AlgAEliGpea2);
00057 this->mAlgorithms_[alg->getName()] = alg;
00058 #endif
00059
00060
00061 GenotypeP gen = static_cast<GenotypeP> (new BitString::BitString);
00062 this->mGenotypes_[gen->getName()] = gen;
00063 gen = static_cast<GenotypeP> (new Binary::Binary);
00064 this->mGenotypes_[gen->getName()] = gen;
00065 gen = static_cast<GenotypeP> (new Tree::Tree);
00066 this->mGenotypes_[gen->getName()] = gen;
00067 gen = static_cast<GenotypeP> (new Permutation::Permutation);
00068 this->mGenotypes_[gen->getName()] = gen;
00069 gen = static_cast<GenotypeP> (new FloatingPoint::FloatingPoint);
00070 this->mGenotypes_[gen->getName()] = gen;
00071
00072
00073
00074
00075 OperatorP op = static_cast<OperatorP> (new TermStagnationOp);
00076 this->allTerminationOps_.push_back(op);
00077 op = static_cast<OperatorP> (new TermMaxGenOp);
00078 this->allTerminationOps_.push_back(op);
00079 op = static_cast<OperatorP> (new TermFitnessValOp);
00080 this->allTerminationOps_.push_back(op);
00081 op = static_cast<OperatorP> (new TermMaxTimeOp);
00082 this->allTerminationOps_.push_back(op);
00083 op = static_cast<OperatorP> (new TermMaxEvalOp);
00084 this->allTerminationOps_.push_back(op);
00085
00086 setRandomizer(static_cast<RandomizerP> (new SimpleRandomizer));
00087 this->registry_ = static_cast<RegistryP> (new Registry);
00088 this->logger_ = static_cast<LoggerP> (new Logger);
00089 this->comm_ = static_cast<CommunicatorP> (new Comm::Communicator);
00090 this->migration_ = static_cast<MigrationP> (new Migration);
00091 }
00092
00093
00098 void State::registerParameters()
00099 {
00100
00101 registry_->registerEntry("milestone.interval", (voidP) (new uint(0)), ECF::UINT);
00102 registry_->registerEntry("milestone.filename", (voidP) (new std::string("milestone.txt")), ECF::STRING);
00103 registry_->registerEntry("batch.repeats", (voidP) (new uint(0)), ECF::UINT);
00104 registry_->registerEntry("batch.singlemilestone", (voidP) (new uint(0)), ECF::UINT);
00105 registry_->registerEntry("batch.statsfile", (voidP) (new std::string("")), ECF::STRING);
00106
00107
00108 registry_->registerEntry("milestone.generation_", (voidP) (new uint(0)), ECF::UINT);
00109 registry_->registerEntry("milestone.elapsedtime_", (voidP) (new uint(0)), ECF::UINT);
00110 registry_->registerEntry("batch.remaining_", (voidP) (new uint(0)), ECF::UINT);
00111 registry_->registerEntry("batch.logfile_", (voidP) (new std::string("")), ECF::STRING);
00112
00113 ECF_LOG(this, 4, "Registering parameters: algorithms, operators");
00114
00115
00116 alg_iter itAlg;
00117 for(itAlg = mAlgorithms_.begin(); itAlg != mAlgorithms_.end(); ++itAlg)
00118 itAlg->second->registerParameters(state_);
00119
00120
00121 mAlgorithms_.begin()->second->registerParallelParameters(state_);
00122
00123
00124 for(uint i = 0; i < allTerminationOps_.size(); i++)
00125 allTerminationOps_[i]->registerParameters(state_);
00126
00127
00128 for(uint i = 0; i < allUserOps_.size(); i++)
00129 allUserOps_[i]->registerParameters(state_);
00130
00131 mutation_->registerParameters(state_);
00132 crossover_->registerParameters(state_);
00133 randomizer_->registerParameters(state_);
00134 population_->registerParameters(state_);
00135 logger_->registerParameters(state_);
00136 migration_->registerParameters(state_);
00137 evalOp_->registerParameters(state_);
00138 }
00139
00140
00145 void State::readParameters()
00146 {
00147 ECF_LOG(this, 4, "Rading parameters from the Registry");
00148
00149
00150 if(registry_->isModified("milestone.filename"))
00151 bSaveMilestone_ = true;
00152 else
00153 bSaveMilestone_ = false;
00154
00155 voidP sptr = registry_->getEntry("milestone.interval");
00156 milestoneInterval_ = *((uint*) sptr.get());
00157
00158 sptr = registry_->getEntry("milestone.filename");
00159 milestoneFilename_ = *((std::string*) sptr.get());
00160
00161
00162 if(registry_->isModified("milestone.generation_"))
00163 bLoadMilestone_ = true;
00164 else
00165 bLoadMilestone_ = false;
00166
00167 sptr = registry_->getEntry("milestone.generation_");
00168 milestoneGeneration_ = *((uint*) sptr.get());
00169
00170 sptr = registry_->getEntry("milestone.elapsedtime_");
00171 milestoneElapsedTime_ = *((uint*) sptr.get());
00172
00173
00174 sptr = registry_->getEntry("batch.repeats");
00175 batchRepeats_ = *((uint*) sptr.get());
00176
00177 sptr = registry_->getEntry("batch.remaining_");
00178 batchRemaining_ = *((uint*) sptr.get());
00179
00180 sptr = registry_->getEntry("batch.statsfile");
00181 batchStatsFile_ = *((std::string*) sptr.get());
00182
00183 sptr = registry_->getEntry("batch.logfile_");
00184 batchLogFile_ = *((std::string*) sptr.get());
00185
00186 sptr = registry_->getEntry("batch.singlemilestone");
00187 bBatchSingleMilestone_ = (*((uint*) sptr.get()) % 2) ? true:false;
00188
00189 if(registry_->isModified("batch.repeats") && batchRepeats_ > 1)
00190 bBatchStart_ = true;
00191 else
00192 bBatchStart_ = false;
00193 }
00194
00195
00201 bool State::parseConfig(std::string filename)
00202 {
00203 std::ifstream fin(filename.c_str());
00204 if (!fin) {
00205 throw std::string("Error opening file " + filename);
00206 }
00207 std::cout << "Parsing configuration file: " << filename << std::endl;
00208
00209 std::string xmlFile, temp;
00210 while (!fin.eof()) {
00211 getline(fin, temp);
00212 xmlFile += "\n" + temp;
00213 }
00214
00215 XMLResults results;
00216 xConfig_ = XMLNode::parseString(xmlFile.c_str(), "ECF", &results);
00217 if (results.error != eXMLErrorNone) {
00218 std::cerr << "Configuration file: " << XMLNode::getError(results.error);
00219 std::cerr << " (line " << results.nLine << ", col " << results.nColumn << ")" << std::endl;
00220 throw("");
00221 }
00222
00223 if (xConfig_.isEmpty())
00224 return false;
00225
00226 int n = xConfig_.nChildNode();
00227 for (int i = 0; i < n; ++i) {
00228 XMLNode child = xConfig_.getChildNode(i);
00229 std::string name = child.getName();
00230 bool ok = true;
00231
00232 if (name == NODE_REGISTRY)
00233 ok &= registry_->readEntries(child);
00234 else if (name == NODE_ALGORITHM)
00235 ok &= parseAlgorithmNode(child);
00236 else if (name == NODE_GENOTYPE)
00237 ok &= parseGenotypeNode(child);
00238 else if (name == NODE_POPULATION)
00239 continue;
00240 else
00241 std::cerr << "Unknown node: " << name << std::endl;
00242
00243 if (!ok)
00244 throw "";
00245 }
00246
00247 return true;
00248 }
00249
00250
00256 bool State::parseAlgorithmNode(XMLNode node)
00257 {
00258 int n = node.nChildNode();
00259 if (n > 1)
00260 std::cout << "Warning: multiple Algorithm nodes found! (using the first one)" << std::endl;
00261
00262 XMLNode child = node.getChildNode(0);
00263 alg_iter alg = mAlgorithms_.find(child.getName());
00264 if (alg == mAlgorithms_.end()) {
00265 throw std::string("Error: unknown Algorithm : ") + child.getName();
00266 }
00267
00268 algorithm_ = alg->second;
00269 bAlgorithmSet_ = true;
00270
00271 if (! registry_->readEntries(child, child.getName()))
00272 return false;
00273
00274 return true;
00275 }
00276
00277
00283 bool State::parseGenotypeNode(XMLNode node)
00284 {
00285 int n = node.nChildNode();
00286 for (int i = 0; i < n; ++i) {
00287 XMLNode child = node.getChildNode(i);
00288 gen_iter gen = mGenotypes_.find(child.getName());
00289 if (gen == mGenotypes_.end()) {
00290 throw std::string("Error: unknown Genotype : ") + child.getName();
00291 }
00292
00293 uint genotypeId = (uint) genotype_.size();
00294 gen->second->setGenotypeId(genotypeId);
00295 gen->second->registerParameters(state_);
00296 setGenotype(gen->second);
00297
00298 if (! registry_->readEntries(child, child.getName(), genotypeId))
00299 return false;
00300 }
00301
00302 return true;
00303 }
00304
00305
00312 bool State::initializeComponents(int argc, char **argv)
00313 {
00314 try {
00315
00316 context_->initialize();
00317
00318 logger_->initialize(state_);
00319 randomizer_->initialize(state_);
00320
00321
00322
00323
00324 ECF_LOG(this, 4, "Initializing active genotypes...");
00325 for(uint i = 0; i < genotype_.size(); i++) {
00326 GenotypeP copy = (GenotypeP) genotype_[i]->copy();
00327 bInitialized_ &= copy->initialize(state_);
00328 }
00329 if(!bInitialized_) {
00330 throw "Error: Genotype initialization failed!";
00331 }
00332
00333
00334 bInitialized_ &= comm_->initialize(state_, argc, argv);
00335
00336
00337 ECF_LOG(this, 4, "Initializing population and algorithm...");
00338 algorithm_->evalOp_ = this->evalOp_;
00339 algorithm_->crossover_ = crossover_;
00340 algorithm_->mutation_ = mutation_;
00341 algorithm_->state_ = state_;
00342 algorithm_->initialize(state_);
00343
00344 population_->initialize(state_);
00345 algorithm_->initializeParallel(state_);
00346
00347 ECF_LOG(this, 4, "Initializing genetic operators...");
00348 mutation_->initialize(state_);
00349 crossover_->initialize(state_);
00350 migration_->initialize(state_);
00351
00352
00353 ECF_LOG(this, 4, "Initializing termination operators...");
00354 activeTerminationOps_.clear();
00355 for(uint i = 0; i < allTerminationOps_.size(); i++)
00356 if(allTerminationOps_[i]->initialize(state_))
00357 activeTerminationOps_.push_back(allTerminationOps_[i]);
00358
00359 if(activeTerminationOps_.empty())
00360 activeTerminationOps_.push_back(allTerminationOps_[0]);
00361
00362
00363 ECF_LOG(this, 4, "Initializing user defined operators...");
00364 activeUserOps_.clear();
00365 for(uint i = 0; i < allUserOps_.size(); i++)
00366 if(allUserOps_[i]->initialize(state_))
00367 activeUserOps_.push_back(allUserOps_[i]);
00368
00369
00370 ECF_LOG(this, 4, "Initializing evaluation operator...");
00371 if(!evalOp_->initialize(state_))
00372 throw "Error: Evaluation operator initialization failed!";
00373
00374
00375 ECF_LOG(this, 4, "Testing evaluation operator...");
00376 individual_ = (IndividualP) (new Individual(state_));
00377 fitness_ = evalOp_->evaluate(individual_);
00378
00379 }
00380
00381 catch(std::string& msg) {
00382 std::cerr << msg << std::endl;
00383 bInitialized_ = false;
00384 }
00385 catch(const char* msg) {
00386 std::cerr << msg << std::endl;
00387 bInitialized_ = false;
00388 }
00389 catch(...) {
00390 std::cerr << "Unknown error in initialization!" << std::endl;
00391 bInitialized_ = false;
00392 }
00393
00394 return bInitialized_;
00395 }
00396
00397
00404 bool State::runBatch()
00405 {
00406 bBatchStart_ = false;
00407 bBatchMode_ = true;
00408
00409 bool bUseLog = registry_->isModified("log.filename");
00410
00411 if(!bLoadMilestone_)
00412 batchRemaining_ = batchRepeats_;
00413 uint numerals = 1 + (uint) (log((double) batchRepeats_) / log((double) 10.));
00414
00415
00416 std::string logFileName = *(std::string*) registry_->getEntry("log.filename").get();
00417 std::string logFileExt = "";
00418 if(bLoadMilestone_)
00419 logFileName = batchLogFile_;
00420 else
00421 batchLogFile_ = logFileName;
00422
00423 if(logFileName.find(".") != std::string::npos) {
00424 logFileExt = logFileName.substr(logFileName.find("."));
00425 logFileName = logFileName.substr(0, logFileName.find("."));
00426 }
00427
00428
00429 std::string milestoneName = *(std::string*) registry_->getEntry("milestone.filename").get();
00430 std::string milestoneExt = "";
00431 if(milestoneName.find(".") != std::string::npos) {
00432 milestoneExt = milestoneName.substr(milestoneName.find("."));
00433 milestoneName = milestoneName.substr(0, milestoneName.find("."));
00434 }
00435
00436
00437 std::ofstream statsFile;
00438 if(registry_->isModified("batch.statsfile")) {
00439 if(bLoadMilestone_)
00440 statsFile.open(batchStatsFile_.c_str(), std::ios_base::app);
00441 else {
00442 statsFile.open(batchStatsFile_.c_str());
00443 statsFile << "runId\tfit_min\tfit_max\tfit_avg\tfit_std\n";
00444 }
00445 if(!statsFile) {
00446 ECF_LOG_ERROR(this, "Error: can't open batch statsfile (" + batchStatsFile_ + ")!");
00447 return false;
00448 }
00449 statsFile.close();
00450 bBatchWriteStats_ = true;
00451 }
00452
00453 uint runId = batchRepeats_ - batchRemaining_ + 1;
00454
00455
00456 for(; runId <= batchRepeats_; runId++) {
00457
00458 if(bUseLog) {
00459 std::stringstream ss;
00460 ss << std::setw(numerals) << std::setfill('0') << runId;
00461 std::string currentLogName = logFileName + "_" + ss.str() + logFileExt;
00462 registry_->modifyEntry("log.filename", (voidP) new std::string(currentLogName));
00463 }
00464
00465
00466 if(!bBatchSingleMilestone_) {
00467 std::stringstream ss;
00468 ss << std::setw(numerals) << std::setfill('0') << runId;
00469 milestoneFilename_ = milestoneName + "_" + ss.str() + milestoneExt;
00470 }
00471
00472
00473 batchRemaining_--;
00474 bInitialized_ = true;
00475 if(!initializeComponents(argc_, argv_))
00476 break;
00477 ECF_LOG(this, 1, "Running in batch mode: run " + uint2str(runId) + "/" + uint2str(batchRepeats_));
00478 run();
00479
00480
00481 if(comm_->getCommGlobalRank() == 0) {
00482 if(bBatchWriteStats_) {
00483 statsFile.open(batchStatsFile_.c_str(), std::ios_base::app);
00484 std::vector<double> stats = population_->getStats()->getStats();
00485 statsFile << runId << '\t';
00486 statsFile << stats[0] << '\t' << stats[1] << '\t' << stats[2] << '\t' << stats[3] << '\n';
00487 statsFile.close();
00488 }
00489 }
00490 }
00491
00492
00493
00494 bBatchMode_ = false;
00495 comm_->finalize();
00496
00497 if(bInitialized_)
00498 std::cout << "Batch mode end (" << batchRepeats_ << " runs concluded)." << std::endl;
00499
00500 if(statsFile)
00501 statsFile.close();
00502 return true;
00503 }
00504
00505
00506
00517 bool State::initialize(int argc, char **argv)
00518 {
00519 this->state_ = this->getState();
00520
00521 genotype_.clear();
00522 mutation_->operators.clear();
00523 crossover_->operators.clear();
00524
00525 bInitialized_ = true;
00526 argc_ = argc;
00527 argv_ = argv;
00528
00529 try {
00530
00531 std::cout << "-- ECF, version " << ECF_VERSION << " --" << std::endl;
00532
00533 if(!bEvaluatorSet_) {
00534 throw "Error: no EvaluateOp defined!";
00535 }
00536
00537
00538 std::string config_file;
00539 if (argc > 1)
00540 config_file = argv[1];
00541
00542 registerParameters();
00543
00544 if (config_file != "") {
00545 bInitialized_ = parseConfig(config_file);
00546 }
00547 else {
00548 std::cout << "Warning: no configuration file given." << std::endl;
00549 std::cout << "Example usage: <ECF_executable> <parameter_file>" << std::endl;
00550 }
00551
00552
00553 if (!bAlgorithmSet_)
00554 algorithm_ = mAlgorithms_.find("SteadyStateTournament")->second;
00555
00556 if(!bGenotypeSet_) {
00557 throw "Error: no Genotype defined!";
00558 }
00559
00560 readParameters();
00561
00562 if(bBatchStart_)
00563 return true;
00564
00565 initializeComponents(argc, argv);
00566
00567 if(bLoadMilestone_)
00568 loadMilestone();
00569
00570 ECF_LOG(this, 4, "Initialization complete.");
00571
00572 }
00573
00574 catch(std::string& msg) {
00575 std::cerr << msg << std::endl;
00576 bInitialized_ = false;
00577 }
00578 catch(const char* msg) {
00579 std::cerr << msg << std::endl;
00580 bInitialized_ = false;
00581 }
00582 catch(...) {
00583 std::cerr << "Unknown error in initialization!" << std::endl;
00584 bInitialized_ = false;
00585 }
00586
00587 return bInitialized_;
00588 }
00589
00590
00594 bool State::isImplicitParallel()
00595 { return algorithm_->isImplicitParallel(); }
00596
00597
00601 bool State::isAlgorithmParallel()
00602 { return algorithm_->isParallel(); }
00603
00604
00609 void State::write(XMLNode& xState)
00610 {
00611 registry_->modifyEntry("milestone.generation_", (voidP) (new uint(getGenerationNo())));
00612 registry_->modifyEntry("milestone.elapsedtime_", (voidP) (new time_t(elapsedTime_)));
00613 registry_->modifyEntry("batch.remaining_", (voidP) (new uint(batchRemaining_)));
00614 if(registry_->isModified("log.filename"))
00615 registry_->modifyEntry("batch.logfile_", (voidP) (new std::string(batchLogFile_)));
00616 }
00617
00618
00623 void State::saveMilestone()
00624 {
00625 XMLNode xMainNode = XMLNode::createXMLTopNode("ECF");
00626 xMainNode.addAttribute("milestone", ctime(¤tTime_));
00627
00628 XMLNode xMilestone;
00629 this->write(xMilestone);
00630 xMainNode.addChild(xMilestone);
00631
00632 XMLNode xNode = this->xConfig_.getChildNode(NODE_ALGORITHM);
00633 xNode = xNode.deepCopy();
00634 xMainNode.addChild(xNode);
00635 xNode = this->xConfig_.getChildNode(NODE_GENOTYPE);
00636 xNode = xNode.deepCopy();
00637 xMainNode.addChild(xNode);
00638
00639 this->registry_->write(xNode);
00640 xMainNode.addChild(xNode);
00641
00642
00643 XMLNode xPopulation;
00644 population_->write(xPopulation);
00645 xMainNode.addChild(xPopulation);
00646
00647 #ifdef _MPI
00648 if(comm_->getCommGlobalRank() != 0)
00649 return;
00650 #endif
00651
00652 xMainNode.writeToFile(milestoneFilename_.c_str());
00653 }
00654
00655
00660 void State::loadMilestone()
00661 {
00662 ECF_LOG(this, 4, "Loading population and evolutionary context from milestone...");
00663 XMLNode xPopulation = xConfig_.getChildNode("Population");
00664 population_->read(xPopulation);
00665
00666 context_->generationNo_ = milestoneGeneration_;
00667 }
00668
00669
00670
00671
00672
00673
00674
00684 uint State::setGenotype(GenotypeP genotype)
00685 {
00686 genotype_.push_back((GenotypeP) genotype->copy());
00687 uint index = (uint) genotype_.size() - 1;
00688 genotype_[index]->setGenotypeId(index);
00689 genotype->setGenotypeId(index);
00690
00691 genotype_[index]->registerParameters(state_);
00692
00693
00694 crossover_->operators.push_back(genotype_[index]->getCrossoverOp());
00695 for(uint iOp = 0; iOp < crossover_->operators[index].size(); iOp++) {
00696 crossover_->operators[index][iOp]->myGenotype_ = genotype_[index];
00697 crossover_->operators[index][iOp]->registerParameters(state_);
00698 }
00699
00700 mutation_->operators.push_back(genotype_[index]->getMutationOp());
00701 for(uint iOp = 0; iOp < mutation_->operators[index].size(); iOp++) {
00702 mutation_->operators[index][iOp]->myGenotype_ = genotype_[index];
00703 mutation_->operators[index][iOp]->registerParameters(state_);
00704 }
00705
00706 bGenotypeSet_ = true;
00707 return index;
00708 }
00709
00711 void State::setAlgorithm(AlgorithmP algorithm)
00712 {
00713 algorithm_ = algorithm;
00714 bAlgorithmSet_ = true;
00715 }
00716
00717
00723 void State::setEvalOp(EvaluateOpP eval)
00724 {
00725 evalOp_ = eval;
00726 bEvaluatorSet_ = true;
00727 }
00728
00729
00735 void State::setEvalOp(EvaluateOp* eval)
00736 {
00737 evalOp_ = (EvaluateOpP) eval;
00738 bEvaluatorSet_ = true;
00739 }
00740
00741
00742
00743
00744
00745
00754 bool State::addGenotype(GenotypeP gen)
00755 {
00756 mGenotypes_[gen->getName()] = gen;
00757 return true;
00758 }
00759
00760
00769 bool State::addAlgorithm(AlgorithmP alg)
00770 {
00771 mAlgorithms_[alg->getName()] = alg;
00772 return true;
00773 }
00774
00782 bool State::addOperator(OperatorP op)
00783 {
00784 allUserOps_.push_back(op);
00785 return true;
00786 }
00787
00788
00789
00790
00791
00792
00793
00794 #ifndef _MPI
00795
00801 bool State::run()
00802 {
00803 if(!bInitialized_) {
00804 std::cerr << "Error: Initialization failed!" << std::endl;
00805 return false;
00806 }
00807
00808 if(bBatchStart_) {
00809 ECF_LOG(this, 5, "Batch mode detected: running batch");
00810 runBatch();
00811 return true;
00812 }
00813
00814 startTime_ = time(NULL);
00815 std::string stime = ctime(&startTime_);
00816 ECF_LOG(this, 3, "Start time: " + stime);
00817
00818 startTime_ -= milestoneElapsedTime_;
00819
00820
00821 ECF_LOG(this, 2, "Evaluating initial population...");
00822 algorithm_->initializePopulation(state_);
00823
00824 currentTime_ = time(NULL);
00825 elapsedTime_ = currentTime_ - startTime_;
00826 ECF_LOG(this, 2, "Generation: " + uint2str(context_->generationNo_));
00827 ECF_LOG(this, 2, "Elapsed time: " + uint2str((uint) elapsedTime_));
00828 population_->updateDemeStats();
00829
00830 ECF_LOG(this, 4, "Checking termination conditions...");
00831 for(uint i = 0; i < activeTerminationOps_.size(); i++)
00832 activeTerminationOps_[i]->operate(state_);
00833
00834
00835 while(context_->bTerminate_ == false) {
00836 ECF_LOG(this, 5, "Calling the active algorithm");
00837 algorithm_->advanceGeneration(state_);
00838 context_->generationNo_++;
00839
00840 currentTime_ = time(NULL);
00841 elapsedTime_ = currentTime_ - startTime_;
00842 ECF_LOG(this, 2, "Generation: " + uint2str(context_->generationNo_));
00843 ECF_LOG(this, 2, "Elapsed time: " + uint2str((uint) elapsedTime_));
00844
00845 population_->updateDemeStats();
00846
00847
00848 ECF_LOG(this, 4, "Calling user defined operators...");
00849 for(uint i = 0; i < activeUserOps_.size(); i++)
00850 activeUserOps_[i]->operate(state_);
00851
00852
00853 ECF_LOG(this, 4, "Checking termination conditions...");
00854 for(uint i = 0; i < activeTerminationOps_.size(); i++)
00855 activeTerminationOps_[i]->operate(state_);
00856
00857 logger_->saveTo();
00858
00859 if(bSaveMilestone_ &&
00860 milestoneInterval_ > 0 && context_->generationNo_ % milestoneInterval_ == 0)
00861 saveMilestone();
00862
00863 migration_->operate(state_);
00864 }
00865
00866
00867 XMLNode xHoF;
00868 population_->getHof()->write(xHoF);
00869 char *out = xHoF.createXMLString(true);
00870 ECF_LOG(this, 1, "\nBest of run: \n" + std::string(out));
00871 freeXMLString(out);
00872
00873
00874 logger_->saveTo(true);
00875 if(bSaveMilestone_)
00876 saveMilestone();
00877
00878 logger_->closeLog();
00879
00880 return true;
00881 }
00882
00883
00884 #else // _MPI
00885
00891 bool State::run()
00892 {
00893 if(bBatchStart_) {
00894 runBatch();
00895 return true;
00896 }
00897
00898
00899 if(!bInitialized_) {
00900 std::cerr << "Error: Initialization failed!" << std::endl;
00901 logger_->saveTo();
00902 if(comm_->isInitialized())
00903 comm_->finalize();
00904 return false;
00905 }
00906
00907 startTime_ = time(NULL);
00908 std::string stime = ctime(&startTime_);
00909 ECF_LOG(this, 3, "Start time: " + stime);
00910
00911 startTime_ -= milestoneElapsedTime_;
00912
00913
00914
00915
00916 if(comm_->getCommRank() == 0) {
00917 ECF_LOG(this, 2, "Evaluating initial population...");
00918 }
00919
00920
00921 algorithm_->initializePopulation(state_);
00922 comm_->synchronize();
00923
00924 if(comm_->getCommRank() == 0) {
00925
00926 if(isImplicitParallel())
00927 algorithm_->initializeImplicit(state_);
00928 }
00929
00930
00931 while(context_->bTerminate_ == false) {
00932
00933 currentTime_ = time(NULL);
00934 elapsedTime_ = currentTime_ - startTime_;
00935 if(comm_->getCommGlobalRank() == 0) {
00936 ECF_LOG(this, 2, "Generation: " + uint2str(context_->generationNo_));
00937 ECF_LOG(this, 2, "Elapsed time: " + uint2str((uint) elapsedTime_));
00938 }
00939
00940
00941 if(comm_->getCommRank() == 0) {
00942 population_->updateDemeStats();
00943
00944 if(bSaveMilestone_ && milestoneInterval_ > 0 && context_->generationNo_ % milestoneInterval_ == 0)
00945 saveMilestone();
00946 }
00947
00948
00949 if(comm_->getCommGlobalRank() == 0) {
00950 ECF_LOG(this, 4, "Checking termination conditions...");
00951 for(uint i = 0; i < activeTerminationOps_.size(); i++)
00952 activeTerminationOps_[i]->operate(state_);
00953
00954 for(uint i = 1; i < population_->getNoDemes(); i++)
00955 comm_->sendTerminateMessage(comm_->getDemeMaster(i), context_->bTerminate_);
00956 }
00957
00958 else if(comm_->getCommRank() == 0)
00959 context_->bTerminate_ = comm_->recvTerminateMessage(0);
00960
00961
00962 algorithm_->bcastTermination(state_);
00963
00964
00965 if(comm_->getCommRank() == 0) {
00966 migration_->operate(state_);
00967 }
00968
00969
00970 ECF_LOG(this, 4, "Calling user defined operators...");
00971 for(uint i = 0; i < activeUserOps_.size(); i++)
00972 activeUserOps_[i]->operate(state_);
00973
00974 logger_->saveTo();
00975
00976 if(context_->bTerminate_ == true)
00977 break;
00978
00979 ECF_LOG(this, 5, "Calling the active algorithm");
00980 algorithm_->advanceGeneration(state_);
00981 context_->generationNo_++;
00982 }
00983
00984 logger_->setLogFrequency(1);
00985 if(comm_->getCommGlobalRank() == 0) {
00986
00987 XMLNode xHoF;
00988 population_->getHof()->write(xHoF);
00989 std::string out = xHoF.createXMLString(true);
00990 ECF_LOG(this, 1, "\nBest of run: \n" + out);
00991
00992 logger_->saveTo(true);
00993 }
00994
00995 if(comm_->getCommRank() == 0 && bSaveMilestone_)
00996 saveMilestone();
00997
00998 logger_->saveTo(true);
00999
01000
01001 comm_->finalize();
01002
01003 return true;
01004 }
01005 #endif // _MPI