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