• Main Page
  • Modules
  • Classes
  • Files
  • File List

D:/Projekt/ECF_trunk/ECF/State.cpp

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);   // XML encoding
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     // register existing components:
00032     // algorithms
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     // paralel algorithms
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     // genotypes
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 //  gen = static_cast<GenotypeP> (new cart::Cartesian);
00070 //  this->mGenotypes_[gen->getName()] = gen;
00071 
00072     // termination operators
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     // State parameters
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     // milestone data
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     // call registerParameters() methods:
00114     alg_iter itAlg;
00115     for(itAlg = mAlgorithms_.begin(); itAlg != mAlgorithms_.end(); itAlg++)
00116         itAlg->second->registerParameters(state_);
00117 
00118     // register common implicit parallel parameters (defined in Algorithm base class)
00119     mAlgorithms_.begin()->second->registerParallelParameters(state_);
00120 
00121     // register termination operators' parameters
00122     for(uint i = 0; i < allTerminationOps_.size(); i++)
00123         allTerminationOps_[i]->registerParameters(state_);
00124 
00125     // user-defined operators
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     // milestone saving data
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     // milestone loading data
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     // batch running data
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         // initialize evolutionary context
00312         context_->initialize();
00313 
00314         logger_->initialize(state_);
00315         randomizer_->initialize(state_);
00316 
00317         // initialize single instance of active genotypes
00318         // (active genotypes - the ones that the individuals are made of, which is defined in the configuration file)
00319         // State keeps a single uninitialized object of all active Genotypes
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         // MPI communicator
00330         bInitialized_ &= comm_->initialize(state_, argc, argv);
00331 
00332         // damo algoritmu pointer na operator evaluacije i pointere na repozitorij krizanja i mutacije
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_); // provjera impl. paralelizacije (nakon population_->initialize zbog podjele procesa po demovima)
00342 
00343         ECF_LOG(this, 4, "Initializing genetic operators...");
00344         mutation_->initialize(state_);
00345         crossover_->initialize(state_);
00346         migration_->initialize(state_);
00347 
00348         // initialize termination ops
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         // if no term operators are configured, activate default (the first)
00355         if(activeTerminationOps_.size() == 0)
00356             activeTerminationOps_.push_back(allTerminationOps_[0]);
00357 
00358         // initialize user ops
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         // evaluation op. initializes last
00366         ECF_LOG(this, 4, "Initializing evaluation operator...");
00367         if(!evalOp_->initialize(state_))
00368             throw "Error: Evaluation operator initialization failed!";
00369 
00370         // generate one individual and fitness object
00371         ECF_LOG(this, 4, "Testing evaluation operator...");
00372         individual_ = (IndividualP) (new Individual(state_));
00373         fitness_ = evalOp_->evaluate(individual_);
00374 
00375     } // try
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     // get logfile name and extension
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     // get milestone name and extension
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     // (re)open stats file, if defined
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     // perform algorithm runs
00452     for(; runId <= batchRepeats_; runId++) {
00453         // set current logfile
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         // set current milestone
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         // run
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         // write stats (PECF: only master process)
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     // ugly workabout for MPI_Finalize, which may only be called once
00489     // (shouldn't be called at the end of a single run)
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(); // obtain a sptr to this
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         // parse arguments: currently only the configuration file's name
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         // use the default algorithm
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     } // try
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(&currentTime_));
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     // save population
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 // setting components
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     // read genotype's operators and register their parameters
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 // adding components
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 // run methods
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     // adjust with previous runtime (from milestone)
00814     startTime_ -= milestoneElapsedTime_;
00815 
00816     // evaluate initial population
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     // run the algorithm
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         // call user-defined operators
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         // termination ops
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     // output HallOfFame
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     //population_->stats_->output(1);
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     // TODO: perform AND_reduce with bInitialized on all processes
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     // adjust with previous runtime (from milestone)
00907     startTime_ -= milestoneElapsedTime_;
00908 
00909     // in PECF, every process works with deme '0'
00910     // 'deme masters' - processes with index 0 in local communicator
00911     // only deme masters know of whole population
00912     if(comm_->getCommRank() == 0) {
00913         ECF_LOG(this, 2, "Evaluating initial population...");
00914     }
00915 
00916     // every process participates in the initial population evaluation
00917     algorithm_->initializePopulation(state_);
00918     comm_->synchronize();
00919 
00920     currentTime_ = time(NULL);
00921     elapsedTime_ = currentTime_ - startTime_;
00922 
00923     if(comm_->getCommRank() == 0) {
00924         // dodatna inicijalizacija za implicitni paralelizam - mozda promijeniti...
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     // run the algorithm
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         // deme masters initiate population statistics and HoF update
00951         if(comm_->getCommRank() == 0) {
00952             population_->updateDemeStats();
00953 
00954             if(bSaveMilestone_ && milestoneInterval_ > 0 && context_->generationNo_ % milestoneInterval_ == 0)
00955                 saveMilestone();
00956         }
00957 
00958         // global process 0 checks termination condition and signals deme masters
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         // deme masters receive info
00968         else if(comm_->getCommRank() == 0)
00969             context_->bTerminate_ = comm_->recvTerminateMessage(0);
00970 
00971         // deme masters signal workers of evolution continuation
00972         algorithm_->bcastTermination(state_);
00973 
00974         // deme masters call migration operator
00975         if(comm_->getCommRank() == 0) {
00976             migration_->operate(state_);
00977         }
00978 
00979         // call user-defined operators
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         // output HallOfFame
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     // communicator
01004     comm_->finalize();
01005 
01006     return true;
01007 }
01008 #endif // _MPI

Generated on Thu Oct 6 2011 13:41:01 for ECF by  doxygen 1.7.1