# t-eoSharing.cpp

    00001 #ifdef HAVE_CONFIG_H
    00002 #include <config.h>
    00003 #endif
    00004
    00005 // to avoid long name warnings
    00006 #ifdef _MSC_VER
    00007 #pragma warning(disable:4786)
    00008 #endif
    00009
    00010 #include <iostream>
    00011 #include <sstream>
    00012 #include <stdexcept>
    00013 #include <vector>
    00014
    00015 // general
    00016 #include <eo>
    00017 #include <utils/eoDistance.h>
    00018
    00019 //-----------------------------------------------------------------------------
    00020
    00021 struct Dummy : public EO<double>
    00022 {
    00023     typedef double Type;
    00024   void printOn(std::ostream & _os) const
    00025   {
    00026       EO<double>::printOn(_os);
    00027       std::cout << " " << xdist ;
    00028   }
    00029   double xdist;
    00030 };
    00031
    00032 class
    00033 eoDummyDistance : public eoDistance<Dummy>
    00034 {
    00035   double operator()(const Dummy & _v1, const Dummy & _v2)
    00036   {
    00037     double r= _v1.xdist - _v2.xdist;
    00038     return sqrt(r*r);
    00039   }
    00040 };
    00041
    00042
    00043 bool operator==(const Dummy & _d1, const Dummy & _d2)
    00044 {
    00045   return _d1.fitness() == _d2.fitness();
    00046 }
    00047
    00048 struct eoDummyPop : public eoPop<Dummy>
    00049 {
    00050 public :
    00051     eoDummyPop(int s=0) { resize(s); }
    00052 };
    00053
    00054 // helper - DOES NOT WORK if different individuals have same fitness!!!
    00055 template <class EOT>
    00056 unsigned isInPop(EOT & _indi, eoPop<EOT> & _pop)
    00057 {
    00058   for (unsigned i=0; i<_pop.size(); i++)
    00059     if (_pop[i] == _indi)
    00060       return i;
    00061   return _pop.size();
    00062 }
    00063
    00064 unsigned int pSize;             // global variable, bouh!
    00065 std::string fitnessType;                // yes, a global variable :-)
    00066 eoDummyPop parentsOrg;
    00067
    00068 template <class EOT>
    00069 void testSelectMany(eoSelect<EOT> & _select, std::string _name)
    00070 {
    00071     unsigned i;
    00072   std::cout << "\n\n" << fitnessType + _name << std::endl;
    00073   std::cout << "===============\n";
    00074
    00075     eoDummyPop parents(parentsOrg);
    00076     eoDummyPop offspring(0);
    00077
    00078     // do the selection
    00079     _select(parents, offspring);
    00080
    00081     //    cout << "Pop offspring \n" << offspring << endl;
    00082
    00083     // compute stats
    00084     std::vector<unsigned> nb(parents.size(), 0);
    00085     for (i=0; i<offspring.size();  i++)
    00086       {
    00087         unsigned trouve = isInPop<Dummy>(offspring[i], parents);
    00088         if (trouve == parents.size()) // pas trouve
    00089           throw std::runtime_error("Pas trouve ds parents");
    00090         nb[trouve]++;
    00091        }
    00092     // dump to file so you can plot using gnuplot - dir name is hardcoded!
    00093     std::string fName = "ResSelect/" + fitnessType + _name + ".select";
    00094     std::ofstream os(fName.c_str());
    00095     for (i=0; i<parents.size();  i++)
    00096       {
    00097         std::cout << i << " -> " << ( (double)nb[i])/offspring.size() << std::endl;
    00098         os << i << " " << ( (double)nb[i])/offspring.size() << std::endl;
    00099       }
    00100
    00101 }
    00102
    00103 template <class EOT>
    00104 void testSelectOne(eoSelectOne<EOT> & _select, eoHowMany & _offspringRate,
    00105                    eoHowMany & _fertileRate, std::string _name)
    00106 {
    00107   eoTruncatedSelectOne<EOT> truncSelect(_select, _fertileRate);
    00108   eoSelectMany<EOT> percSelect(truncSelect, _offspringRate);
    00109   testSelectMany<EOT>(percSelect, _name);
    00110 }
    00111
    00112
    00113 //-----------------------------------------------------------------------------
    00114
    00115 int the_main(int argc, char **argv)
    00116 {
    00117   eoParser parser(argc, argv);
    00118
    00119   // random seed
    00120     eoValueParam<uint32_t>& seedParam = parser.createParam(uint32_t(0), "seed", "Random number seed", 'S');
    00121     if (seedParam.value() == 0)
    00122         seedParam.value() = time(0);
    00123     rng.reseed(seedParam.value());
    00124
    00125
    00126   // pSize global variable !
    00127   eoValueParam<unsigned> pSizeParam = parser.createParam(unsigned(10), "parentSize", "Parent size",'P');
    00128   pSize = pSizeParam.value();
    00129
    00130   eoHowMany oRate = parser.createParam(eoHowMany(1.0), "offsrpringRate", "Offsrpring rate (% or absolute)",'O').value();
    00131
    00132   eoHowMany fRate = parser.createParam(eoHowMany(1.0), "fertileRate", "Fertility rate (% or absolute)",'F').value();
    00133
    00134
    00135   double nicheSize = parser.createParam(0.1, "nicheSize", "Paramter Sigma for Sharing",'\0').value();
    00136
    00137   eoParamParamType & peakParam = parser.createParam(eoParamParamType("2(1,2)"), "peaks", "Description of the peaks: N(nb1,nb2,...,nbN)", 'p').value();
    00138
    00139   // the number of peaks: first item of the paramparam
    00140   unsigned peakNumber = atoi(peakParam.first.c_str());
    00141   if (peakNumber < 2)
    00142       {
    00143         std::cerr << "WARNING, nb of peaks must be larger than 2, using 2" << std::endl;
    00144         peakNumber = 2;
    00145       }
    00146
    00147   std::vector<unsigned> nbIndiPerPeak(peakNumber);
    00148   unsigned i, sum=0;
    00149
    00150   // the second item is a vector<string> containing all values
    00151   if (!peakParam.second.size())   // no other parameter : equal peaks
    00152       {
    00153         std::cerr << "WARNING, no nb of indis per peaks, using equal nbs" << std::endl;
    00154         for (i=0; i<peakNumber; i++)
    00155           nbIndiPerPeak[i] = pSize/peakNumber;
    00156       }
    00157     else          // parameters passed by user
    00158       if (peakParam.second.size() != peakNumber)
    00159         {
    00160           std::cerr << "ERROR, not enough nb of indis per peaks" << std::endl;
    00161           exit(1);
    00162         }
    00163       else    // now we have in peakParam.second all numbers
    00164         {
    00165           for (i=0; i<peakNumber; i++)
    00166             sum += ( nbIndiPerPeak[i] = atoi(peakParam.second[i].c_str()) );
    00167           // now normalize
    00168           for (i=0; i<peakNumber; i++)
    00169             nbIndiPerPeak[i] = nbIndiPerPeak[i] * pSize / sum;
    00170         }
    00171
    00172   // compute exact total
    00173   sum = 0;
    00174   for (i=0; i<peakNumber; i++)
    00175     sum += nbIndiPerPeak[i];
    00176   if (sum != pSize)
    00177     {
    00178       pSize = pSizeParam.value() = sum;
    00179       std::cerr << "WARNING, adjusting pSize to " << pSize << std::endl;
    00180     }
    00181
    00182     make_help(parser);
    00183
    00184     // hard-coded directory name ...
    00185     std::cout << "Testing the Sharing\n";
    00186     std::cout << " There will be " << peakNumber << " peaks";
    00187     std::cout << " with respective pops ";
    00188     for (i=0; i<peakNumber; i++)
    00189       std::cout << nbIndiPerPeak[i] << ", ";
    00190     std::cout << "\n Peaks are at distance 1 from one-another (dim 1),\n";
    00191       std::cout << " fitness of each peak is nb of peak, and\n";
    00192       std::cout << " fitness of individuals = uniform[fitness of peak +- 0.01]\n\n";
    00193
    00194       std::cout << "The resulting file (in dir ResSelect), contains \n";
    00195     std::cout << " the empirical proba. for each indi to be selected." << std::endl;
    00196     system("mkdir ResSelect");
    00197
    00198     // initialize parent population
    00199     parentsOrg.resize(pSize);
    00200
    00201     // all peaks of equal size in fitness, with different nn of individuals
    00202     unsigned index=0;
    00203     for (unsigned nbP=0; nbP<peakNumber; nbP++)
    00204       for (i=0; i<nbIndiPerPeak[nbP]; i++)
    00205         {
    00206           parentsOrg[index].fitness(nbP+1 + 0.02*eo::rng.uniform() - 0.01);
    00207           parentsOrg[index].xdist = nbP+1 + 0.02*eo::rng.uniform() - 0.01;
    00208           index++;
    00209         }
    00210
    00211     std::cout << "Initial population\n" << parentsOrg << std::endl;
    00212
    00213     char fileName[1024];
    00214
    00215 // the selection procedures under test
    00216     //    eoDetSelect<Dummy> detSelect(oRate);
    00217     //    testSelectMany(detSelect, "detSelect");
    00218
    00219     // Sharing using the perf2Worth construct
    00220     // need a distance for that
    00221     eoDummyDistance dist;
    00222     eoSharingSelect<Dummy> newSharingSelect(nicheSize, dist);
    00223     sprintf(fileName,"Niche_%g",nicheSize);
    00224     testSelectOne<Dummy>(newSharingSelect, oRate, fRate, fileName);
    00225
    00226     return 1;
    00227 }
    00228
    00229 int main(int argc, char **argv)
    00230 {
    00231     try
    00232     {
    00233         the_main(argc, argv);
    00234     }
    00235     catch(std::exception& e)
    00236     {
    00237         std::cout << "Exception: " << e.what() << std::endl;
    00238         return 1;
    00239     }
    00240 }