EvolvingObjects
|
#ifdef HAVE_CONFIG_H #include <config.h> #endif // to avoid long name warnings #ifdef _MSC_VER #pragma warning(disable:4786) #endif #include <iostream> #include <sstream> #include <stdexcept> #include <vector> // general #include <eo> #include <utils/eoDistance.h> //----------------------------------------------------------------------------- struct Dummy : public EO<double> { typedef double Type; void printOn(std::ostream & _os) const { EO<double>::printOn(_os); std::cout << " " << xdist ; } double xdist; }; class eoDummyDistance : public eoDistance<Dummy> { double operator()(const Dummy & _v1, const Dummy & _v2) { double r= _v1.xdist - _v2.xdist; return sqrt(r*r); } }; bool operator==(const Dummy & _d1, const Dummy & _d2) { return _d1.fitness() == _d2.fitness(); } struct eoDummyPop : public eoPop<Dummy> { public : eoDummyPop(int s=0) { resize(s); } }; // helper - DOES NOT WORK if different individuals have same fitness!!! template <class EOT> unsigned isInPop(EOT & _indi, eoPop<EOT> & _pop) { for (unsigned i=0; i<_pop.size(); i++) if (_pop[i] == _indi) return i; return _pop.size(); } unsigned int pSize; // global variable, bouh! std::string fitnessType; // yes, a global variable :-) eoDummyPop parentsOrg; template <class EOT> void testSelectMany(eoSelect<EOT> & _select, std::string _name) { unsigned i; std::cout << "\n\n" << fitnessType + _name << std::endl; std::cout << "===============\n"; eoDummyPop parents(parentsOrg); eoDummyPop offspring(0); // do the selection _select(parents, offspring); // cout << "Pop offspring \n" << offspring << endl; // compute stats std::vector<unsigned> nb(parents.size(), 0); for (i=0; i<offspring.size(); i++) { unsigned trouve = isInPop<Dummy>(offspring[i], parents); if (trouve == parents.size()) // pas trouve throw std::runtime_error("Pas trouve ds parents"); nb[trouve]++; } // dump to file so you can plot using gnuplot - dir name is hardcoded! std::string fName = "ResSelect/" + fitnessType + _name + ".select"; std::ofstream os(fName.c_str()); for (i=0; i<parents.size(); i++) { std::cout << i << " -> " << ( (double)nb[i])/offspring.size() << std::endl; os << i << " " << ( (double)nb[i])/offspring.size() << std::endl; } } template <class EOT> void testSelectOne(eoSelectOne<EOT> & _select, eoHowMany & _offspringRate, eoHowMany & _fertileRate, std::string _name) { eoTruncatedSelectOne<EOT> truncSelect(_select, _fertileRate); eoSelectMany<EOT> percSelect(truncSelect, _offspringRate); testSelectMany<EOT>(percSelect, _name); } //----------------------------------------------------------------------------- int the_main(int argc, char **argv) { eoParser parser(argc, argv); // random seed eoValueParam<uint32_t>& seedParam = parser.createParam(uint32_t(0), "seed", "Random number seed", 'S'); if (seedParam.value() == 0) seedParam.value() = time(0); rng.reseed(seedParam.value()); // pSize global variable ! eoValueParam<unsigned> pSizeParam = parser.createParam(unsigned(10), "parentSize", "Parent size",'P'); pSize = pSizeParam.value(); eoHowMany oRate = parser.createParam(eoHowMany(1.0), "offsrpringRate", "Offsrpring rate (% or absolute)",'O').value(); eoHowMany fRate = parser.createParam(eoHowMany(1.0), "fertileRate", "Fertility rate (% or absolute)",'F').value(); double nicheSize = parser.createParam(0.1, "nicheSize", "Paramter Sigma for Sharing",'\0').value(); eoParamParamType & peakParam = parser.createParam(eoParamParamType("2(1,2)"), "peaks", "Description of the peaks: N(nb1,nb2,...,nbN)", 'p').value(); // the number of peaks: first item of the paramparam unsigned peakNumber = atoi(peakParam.first.c_str()); if (peakNumber < 2) { std::cerr << "WARNING, nb of peaks must be larger than 2, using 2" << std::endl; peakNumber = 2; } std::vector<unsigned> nbIndiPerPeak(peakNumber); unsigned i, sum=0; // the second item is a vector<string> containing all values if (!peakParam.second.size()) // no other parameter : equal peaks { std::cerr << "WARNING, no nb of indis per peaks, using equal nbs" << std::endl; for (i=0; i<peakNumber; i++) nbIndiPerPeak[i] = pSize/peakNumber; } else // parameters passed by user if (peakParam.second.size() != peakNumber) { std::cerr << "ERROR, not enough nb of indis per peaks" << std::endl; exit(1); } else // now we have in peakParam.second all numbers { for (i=0; i<peakNumber; i++) sum += ( nbIndiPerPeak[i] = atoi(peakParam.second[i].c_str()) ); // now normalize for (i=0; i<peakNumber; i++) nbIndiPerPeak[i] = nbIndiPerPeak[i] * pSize / sum; } // compute exact total sum = 0; for (i=0; i<peakNumber; i++) sum += nbIndiPerPeak[i]; if (sum != pSize) { pSize = pSizeParam.value() = sum; std::cerr << "WARNING, adjusting pSize to " << pSize << std::endl; } make_help(parser); // hard-coded directory name ... std::cout << "Testing the Sharing\n"; std::cout << " There will be " << peakNumber << " peaks"; std::cout << " with respective pops "; for (i=0; i<peakNumber; i++) std::cout << nbIndiPerPeak[i] << ", "; std::cout << "\n Peaks are at distance 1 from one-another (dim 1),\n"; std::cout << " fitness of each peak is nb of peak, and\n"; std::cout << " fitness of individuals = uniform[fitness of peak +- 0.01]\n\n"; std::cout << "The resulting file (in dir ResSelect), contains \n"; std::cout << " the empirical proba. for each indi to be selected." << std::endl; system("mkdir ResSelect"); // initialize parent population parentsOrg.resize(pSize); // all peaks of equal size in fitness, with different nn of individuals unsigned index=0; for (unsigned nbP=0; nbP<peakNumber; nbP++) for (i=0; i<nbIndiPerPeak[nbP]; i++) { parentsOrg[index].fitness(nbP+1 + 0.02*eo::rng.uniform() - 0.01); parentsOrg[index].xdist = nbP+1 + 0.02*eo::rng.uniform() - 0.01; index++; } std::cout << "Initial population\n" << parentsOrg << std::endl; char fileName[1024]; // the selection procedures under test // eoDetSelect<Dummy> detSelect(oRate); // testSelectMany(detSelect, "detSelect"); // Sharing using the perf2Worth construct // need a distance for that eoDummyDistance dist; eoSharingSelect<Dummy> newSharingSelect(nicheSize, dist); sprintf(fileName,"Niche_%g",nicheSize); testSelectOne<Dummy>(newSharingSelect, oRate, fRate, fileName); return 1; } int main(int argc, char **argv) { try { the_main(argc, argv); } catch(std::exception& e) { std::cout << "Exception: " << e.what() << std::endl; return 1; } }