• 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     alg = static_cast<AlgorithmP> (new DifferentialEvolution);
00048     this->mAlgorithms_[alg->getName()] = alg;
00049 
00050 #ifdef _MPI
00051     // paralel algorithms
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     // genotypes
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 //  gen = static_cast<GenotypeP> (new cart::Cartesian);
00072 //  this->mGenotypes_[gen->getName()] = gen;
00073 
00074     // termination operators
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     // State parameters
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     // milestone data
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     // call registerParameters() methods:
00116     alg_iter itAlg;
00117     for(itAlg = mAlgorithms_.begin(); itAlg != mAlgorithms_.end(); ++itAlg)
00118         itAlg->second->registerParameters(state_);
00119 
00120     // register common implicit parallel parameters (defined in Algorithm base class)
00121     mAlgorithms_.begin()->second->registerParallelParameters(state_);
00122 
00123     // register termination operators' parameters
00124     for(uint i = 0; i < allTerminationOps_.size(); i++)
00125         allTerminationOps_[i]->registerParameters(state_);
00126 
00127     // user-defined operators
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     // milestone saving data
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     // milestone loading data
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     // batch running data
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         // initialize evolutionary context
00316         context_->initialize();
00317 
00318         logger_->initialize(state_);
00319         randomizer_->initialize(state_);
00320 
00321         // initialize single instance of active genotypes
00322         // (active genotypes - the ones that the individuals are made of, which is defined in the configuration file)
00323         // State keeps a single uninitialized object of all active Genotypes
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         // MPI communicator
00334         bInitialized_ &= comm_->initialize(state_, argc, argv);
00335 
00336         // damo algoritmu pointer na operator evaluacije i pointere na repozitorij krizanja i mutacije
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_); // provjera impl. paralelizacije (nakon population_->initialize zbog podjele procesa po demovima)
00346 
00347         ECF_LOG(this, 4, "Initializing genetic operators...");
00348         mutation_->initialize(state_);
00349         crossover_->initialize(state_);
00350         migration_->initialize(state_);
00351 
00352         // initialize termination ops
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         // if no term operators are configured, activate default (the first)
00359         if(activeTerminationOps_.empty())
00360             activeTerminationOps_.push_back(allTerminationOps_[0]);
00361 
00362         // initialize user ops
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         // evaluation op. initializes last
00370         ECF_LOG(this, 4, "Initializing evaluation operator...");
00371         if(!evalOp_->initialize(state_))
00372             throw "Error: Evaluation operator initialization failed!";
00373 
00374         // generate one individual and fitness object
00375         ECF_LOG(this, 4, "Testing evaluation operator...");
00376         individual_ = (IndividualP) (new Individual(state_));
00377         fitness_ = evalOp_->evaluate(individual_);
00378 
00379     } // try
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     // get logfile name and extension
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     // get milestone name and extension
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     // (re)open stats file, if defined
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     // perform algorithm runs
00456     for(; runId <= batchRepeats_; runId++) {
00457         // set current logfile
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         // set current milestone
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         // run
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         // write stats (PECF: only master process)
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     // ugly workabout for MPI_Finalize, which may only be called once
00493     // (shouldn't be called at the end of a single run)
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(); // obtain a sptr to this
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         // parse arguments: currently only the configuration file's name
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         // use the default algorithm
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     } // try
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(&currentTime_));
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     // save population
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 // setting components
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     // read genotype's operators and register their parameters
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 // adding components
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 // run methods
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     // adjust with previous runtime (from milestone)
00818     startTime_ -= milestoneElapsedTime_;
00819 
00820     // evaluate initial population
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     // run the algorithm
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         // call user-defined operators
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         // termination ops
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     // output HallOfFame
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     //population_->stats_->output(1);
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     // TODO: perform AND_reduce with bInitialized on all processes
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     // adjust with previous runtime (from milestone)
00911     startTime_ -= milestoneElapsedTime_;
00912 
00913     // in PECF, every process works with deme '0'
00914     // 'deme masters' - processes with index 0 in local communicator
00915     // only deme masters know of whole population
00916     if(comm_->getCommRank() == 0) {
00917         ECF_LOG(this, 2, "Evaluating initial population...");
00918     }
00919 
00920     // every process participates in the initial population evaluation
00921     algorithm_->initializePopulation(state_);
00922     comm_->synchronize();
00923 
00924     if(comm_->getCommRank() == 0) {
00925         // dodatna inicijalizacija za implicitni paralelizam - mozda promijeniti...
00926         if(isImplicitParallel())
00927             algorithm_->initializeImplicit(state_);
00928     }
00929 
00930     // run the algorithm
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         // deme masters initiate population statistics and HoF update
00941         if(comm_->getCommRank() == 0) {
00942             population_->updateDemeStats();
00943 
00944             if(bSaveMilestone_ && milestoneInterval_ > 0 && context_->generationNo_ % milestoneInterval_ == 0)
00945                 saveMilestone();
00946         }
00947 
00948         // global process 0 checks termination condition and signals deme masters
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         // deme masters receive info
00958         else if(comm_->getCommRank() == 0)
00959             context_->bTerminate_ = comm_->recvTerminateMessage(0);
00960 
00961         // deme masters signal workers of evolution continuation
00962         algorithm_->bcastTermination(state_);
00963 
00964         // deme masters call migration operator
00965         if(comm_->getCommRank() == 0) {
00966             migration_->operate(state_);
00967         }
00968 
00969         // call user-defined operators
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         // output HallOfFame
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     // communicator
01001     comm_->finalize();
01002 
01003     return true;
01004 }
01005 #endif // _MPI

Generated on Fri Jul 5 2013 09:34:23 for ECF by  doxygen 1.7.1