• Main Page
  • Related Pages
  • Classes
  • Files
  • Examples
  • File List
  • File Members

Population.cpp

Go to the documentation of this file.
00001 
00041 #include <SharkDefs.h>
00042 #include <EALib/Population.h>
00043 
00044 
00045 using namespace std;
00046 
00047 //===========================================================================
00048 //
00049 // constructors
00050 //
00051 
00052 Population::Population()
00053 {
00054     subPop    = false;
00055     ascending = false;
00056     spinOnce  = true;
00057 }
00058 
00059 Population::Population(const vector< Individual * >& indvec)
00060         : vector< Individual * >(indvec)
00061 {
00062     subPop    = true;
00063     ascending = false;
00064     spinOnce  = true;
00065 }
00066 
00067 Population::Population(unsigned n)
00068         : vector< Individual * >(n)
00069 {
00070     for (unsigned i = size(); i--;)
00071         *(begin() + i) = new Individual;
00072     subPop    = false;
00073     ascending = false;
00074     spinOnce  = true;
00075 }
00076 
00077 Population::Population(const Individual& indiv)
00078         : vector< Individual * >(1)
00079 {
00080     *begin() = new Individual(indiv);
00081     subPop    = false;
00082     ascending = false;
00083     spinOnce  = true;
00084 }
00085 
00086 Population::Population(unsigned n, const Individual& indiv)
00087         : vector< Individual * >(n)
00088 {
00089     for (unsigned i = size(); i--;)
00090         *(begin() + i) = new Individual(indiv);
00091     subPop    = false;
00092     ascending = false;
00093     spinOnce  = true;
00094 }
00095 
00101 Population::Population(unsigned n, const Chromosome& chrom0)
00102         : vector< Individual * >(n)
00103 {
00104     for (unsigned i = size(); i--;)
00105         *(begin() + i) = new Individual(chrom0);
00106     subPop    = false;
00107     ascending = false;
00108     spinOnce  = true;
00109 }
00110 
00111 
00112 Population::Population(unsigned n, const Chromosome& chrom0,
00113                        const Chromosome& chrom1)
00114         : vector< Individual * >(n)
00115 {
00116     for (unsigned i = size(); i--;)
00117         *(begin() + i) = new Individual(chrom0, chrom1);
00118     subPop    = false;
00119     ascending = false;
00120     spinOnce  = true;
00121 }
00122 
00123 Population::Population(unsigned n, const Chromosome& chrom0,
00124                        const Chromosome& chrom1,
00125                        const Chromosome& chrom2)
00126         : vector< Individual * >(n)
00127 {
00128     for (unsigned i = size(); i--;)
00129         *(begin() + i) = new Individual(chrom0, chrom1, chrom2);
00130     subPop    = false;
00131     ascending = false;
00132     spinOnce  = true;
00133 }
00134 
00135 Population::Population(unsigned n, const Chromosome& chrom0,
00136                        const Chromosome& chrom1,
00137                        const Chromosome& chrom2,
00138                        const Chromosome& chrom3)
00139         : vector< Individual * >(n)
00140 {
00141     for (unsigned i = size(); i--;)
00142         *(begin() + i) = new Individual(chrom0, chrom1, chrom2,
00143                                         chrom3);
00144     subPop    = false;
00145     ascending = false;
00146     spinOnce  = true;
00147 }
00148 
00149 Population::Population(unsigned n, const Chromosome& chrom0,
00150                        const Chromosome& chrom1,
00151                        const Chromosome& chrom2,
00152                        const Chromosome& chrom3,
00153                        const Chromosome& chrom4)
00154         : vector< Individual * >(n)
00155 {
00156     for (unsigned i = size(); i--;)
00157         *(begin() + i) = new Individual(chrom0, chrom1, chrom2,
00158                                         chrom3, chrom4);
00159     subPop    = false;
00160     ascending = false;
00161     spinOnce  = true;
00162 }
00163 
00164 Population::Population(unsigned n, const Chromosome& chrom0,
00165                        const Chromosome& chrom1,
00166                        const Chromosome& chrom2,
00167                        const Chromosome& chrom3,
00168                        const Chromosome& chrom4,
00169                        const Chromosome& chrom5)
00170         : vector< Individual * >(n)
00171 {
00172     for (unsigned i = size(); i--;)
00173         *(begin() + i) = new Individual(chrom0, chrom1, chrom2,
00174                                         chrom3, chrom4, chrom5);
00175     subPop    = false;
00176     ascending = false;
00177     spinOnce  = true;
00178 }
00179 
00180 Population::Population(unsigned n, const Chromosome& chrom0,
00181                        const Chromosome& chrom1,
00182                        const Chromosome& chrom2,
00183                        const Chromosome& chrom3,
00184                        const Chromosome& chrom4,
00185                        const Chromosome& chrom5,
00186                        const Chromosome& chrom6)
00187         : vector< Individual * >(n)
00188 {
00189     for (unsigned i = size(); i--;)
00190         *(begin() + i) = new Individual(chrom0, chrom1, chrom2,
00191                                         chrom3, chrom4, chrom5,
00192                                         chrom6);
00193     subPop    = false;
00194     ascending = false;
00195     spinOnce  = true;
00196 }
00197 
00198 Population::Population(unsigned n, const Chromosome& chrom0,
00199                        const Chromosome& chrom1,
00200                        const Chromosome& chrom2,
00201                        const Chromosome& chrom3,
00202                        const Chromosome& chrom4,
00203                        const Chromosome& chrom5,
00204                        const Chromosome& chrom6,
00205                        const Chromosome& chrom7)
00206         : vector< Individual * >(n)
00207 {
00208     for (unsigned i = size(); i--;)
00209         *(begin() + i) = new Individual(chrom0, chrom1, chrom2,
00210                                         chrom3, chrom4, chrom5,
00211                                         chrom6, chrom7);
00212     subPop    = false;
00213     ascending = false;
00214     spinOnce  = true;
00215 }
00216 
00217 Population::Population(unsigned n, const vector< Chromosome * >& chrom)
00218         : vector< Individual * >(n)
00219 {
00220     Individual indiv(chrom);
00221     for (unsigned i = size(); i--;)
00222         *(begin() + i) = new Individual(indiv);
00223     subPop    = false;
00224     ascending = false;
00225     spinOnce  = true;
00226 }
00227 
00228 Population::Population(const Population& pop)
00229         : vector< Individual * >(pop.size())
00230 {
00231     for (unsigned i = size(); i--;)
00232         *(begin() + i) = new Individual(pop[ i ]);
00233     subPop    = false;
00234     ascending = pop.ascending; //false;
00235     spinOnce  = pop.spinOnce;  //true;
00236 }
00237 
00238 //===========================================================================
00239 //
00240 // destructor
00241 //
00242 Population::~Population()
00243 {
00244     if (! subPop)
00245         for (unsigned i = size(); i--;)
00246             delete *(begin() + i);
00247 }
00248 
00249 //===========================================================================
00250 //
00251 // change size of a population
00252 //
00253 void Population::resize(unsigned n)
00254 {
00255     unsigned i, s = size();
00256     if (n < s) {
00257         for (i = n; i < s; ++i)
00258             delete *(begin() + i);
00259         vector< Individual * >::erase(begin() + n, end());
00260     }
00261     else if (n > size()) {
00262         vector< Individual * >::insert(end(), n - s, (Individual *)NULL);
00263         if (s > 0)
00264             for (i = s; i < n; ++i)
00265                 *(begin() + i) = new Individual(*(*(begin())));
00266         else
00267             for (i = s; i < n; ++i)
00268                 *(begin() + i) = new Individual;
00269     }
00270 }
00271 
00272 //===========================================================================
00273 
00274 Population& Population::operator = (const Individual& ind)
00275 {
00276     for (unsigned i = size(); i--;)
00277         (*this)[ i ] = ind;
00278 
00279     return *this;
00280 }
00281 
00282 //===========================================================================
00283 
00284 Population& Population::operator = (const Population& pop)
00285 {
00286         if(this == &pop) return *this;
00287     SIZE_CHECK(size() == pop.size() || ! subPop)
00288 
00289     unsigned i;
00290 
00291     if (size() != pop.size()) {
00292         for (i = size(); i--;)
00293             delete *(begin() + i);
00294         vector< Individual * >::operator = (pop);
00295         for (i = size(); i--;)
00296             *(begin() + i) = new Individual(pop[ i ]);
00297     }
00298     else
00299         for (i = size(); i--;)
00300             (*this)[ i ] = pop[ i ];
00301 
00302     return *this;
00303 }
00304 
00305 //===========================================================================
00306 
00307 vector< const Chromosome* > Population::matingPool(unsigned chrom,
00308         unsigned from,
00309         unsigned to) const
00310 {
00311     if (from == 0 && to == 0)
00312         to = size() - 1;
00313 
00314     vector< const Chromosome* > pool;
00315 
00316     for (unsigned i = from; i <= to; ++i)
00317         pool.push_back(&(*this)[ i ][ chrom ]);
00318 
00319     return pool;
00320 }
00321 
00322 //===========================================================================
00323 
00324 bool Population::lessFitness(Individual*const& i1, Individual*const& i2)
00325 {
00326     return i1->fitness < i2->fitness;
00327 }
00328 
00329 bool Population::greaterFitness(Individual*const& i1, Individual*const& i2)
00330 {
00331     return i1->fitness > i2->fitness;
00332 }
00333 
00334 void Population::sortIndividuals(vector< Individual * >& indvec)
00335 {
00336     std::sort(indvec.begin(), indvec.end(),
00337               ascending ? Population::lessFitness : Population::greaterFitness);
00338 }
00339 
00340 //===========================================================================
00341 
00342 void Population::sort()
00343 {
00344     sortIndividuals(*this);
00345 }
00346 
00347 //===========================================================================
00348 
00349 void Population::shuffle()
00350 {
00351     for (unsigned i = size(); i--;)
00352         swap(i, Rng::discrete(0, size() - 1));
00353 }
00354 
00355 //===========================================================================
00356 
00357 void Population::replace(unsigned i, const Individual& ind)
00358 {
00359     RANGE_CHECK(i < size())
00360     delete *(begin() + i);
00361     *(begin() + i) = new Individual(ind);
00362 }
00363 
00364 //===========================================================================
00365 
00366 void Population::replace(unsigned i, const Population& pop)
00367 {
00368     RANGE_CHECK(i + pop.size() <= size())
00369     for (unsigned j = pop.size(); j--;)
00370         (*this)[ i+j ] = pop[ j ];
00371 }
00372 
00373 //===========================================================================
00374 
00375 void Population::insert(unsigned i, const Individual& ind)
00376 {
00377     RANGE_CHECK(i <= size())
00378     vector< Individual * >::insert(begin() + i, new Individual(ind));
00379 }
00380 
00381 //===========================================================================
00382 
00383 void Population::insert(unsigned i, const Population& pop)
00384 {
00385     RANGE_CHECK(i <= size())
00386     vector< Individual * >::insert(begin() + i, pop.size(),
00387                                    (Individual *)NULL);
00388     for (unsigned j = pop.size(); j--;)
00389         *(begin() + i + j) = new Individual(pop[ j ]);
00390 }
00391 
00392 //===========================================================================
00393 
00394 void Population::append(const Individual& ind)
00395 {
00396     vector< Individual * >::push_back(new Individual(ind));
00397 }
00398 
00399 //===========================================================================
00400 
00401 void Population::append(const Population& pop)
00402 {
00403     insert(size(), pop);
00404 }
00405 
00406 //===========================================================================
00407 
00408 void Population::remove(unsigned i)
00409 {
00410     RANGE_CHECK(i < size())
00411     delete *(begin() + i);
00412     vector< Individual * >::erase(begin() + i);
00413 }
00414 
00415 //===========================================================================
00416 
00417 void Population::remove(unsigned i, unsigned k)
00418 {
00419     if (i <= k) {
00420         RANGE_CHECK(k < size())
00421         for (unsigned j = i; j < k; j++)
00422             delete *(begin() + j);
00423         vector< Individual * >::erase(begin() + i, begin() + k);
00424     }
00425 }
00426 
00427 //===========================================================================
00428 
00429 void Population::exchange(Population& pop)
00430 {
00431     unsigned buffer1;
00432     bool buffer2;
00433 
00434     SIZE_CHECK(size() == pop.size())
00435 
00436     for (unsigned i = size(); i--;)
00437         std::swap(*(begin() + i), *(pop.begin() + i));
00438 
00439     // Exchanging internal variables:
00440 
00441     buffer1 = index;
00442     index = pop.index;
00443     pop.index = buffer1;
00444     buffer2 = subPop;
00445     subPop = pop.subPop;
00446     pop.subPop = buffer2;
00447     buffer2 = ascending;
00448     ascending = pop.ascending;
00449     pop.ascending = buffer2;
00450     buffer2 = spinOnce;
00451     spinOnce = pop.spinOnce;
00452     pop.spinOnce = buffer2;
00453 }
00454 
00455 //===========================================================================
00456 
00457 Individual& Population::best(Individual& ind0, Individual& ind1) const
00458 {
00459     if ((ascending && ind0.fitness < ind1.fitness) ||
00460             (! ascending && ind0.fitness > ind1.fitness)) {
00461         return ind0;
00462     }
00463     else {
00464         return ind1;
00465     }
00466 }
00467 
00468 Individual& Population::worst(Individual& ind0, Individual& ind1) const
00469 {
00470     if ((ascending && ind0.fitness < ind1.fitness) ||
00471             (! ascending && ind0.fitness > ind1.fitness)) {
00472         return ind1;
00473     }
00474     else {
00475         return ind0;
00476     }
00477 }
00478 
00479 //===========================================================================
00480 
00481 Individual&
00482 Population::oneOfBest()
00483 {
00484     RANGE_CHECK(size() > 0)
00485     vector< unsigned > bestIndices;
00486 
00487     // find indices of all best individuals
00488     // assume unsorted population
00489     for (unsigned i = 0; i < size(); i++) {
00490         if (ascending) {
00491             if ((*this)[ i ].fitness == maxFitness())
00492                 bestIndices.push_back(i);
00493         }
00494         else {
00495             if ((*this)[ i ].fitness == minFitness())
00496                 bestIndices.push_back(i);
00497         }
00498     }
00499 
00500     // return random "best" individual
00501     return((*this)[ bestIndices[ Rng::discrete(0, bestIndices.size() - 1)] ]);
00502 }
00503 
00504 const Individual&
00505 Population::oneOfBest() const
00506 {
00507     RANGE_CHECK(size() > 0)
00508     vector< unsigned > bestIndices;
00509 
00510     // find indices of all best individuals
00511     // assume unsorted population
00512     for (unsigned i = 0; i < size(); i++) {
00513         if (ascending) {
00514             if ((*this)[ i ].fitness == maxFitness())
00515                 bestIndices.push_back(i);
00516         }
00517         else {
00518             if ((*this)[ i ].fitness == minFitness())
00519                 bestIndices.push_back(i);
00520         }
00521     }
00522 
00523     // return random "best" individual
00524     return((*this)[ bestIndices[ Rng::discrete(0, bestIndices.size() - 1)] ]);
00525 }
00526 
00527 //===========================================================================
00528 
00529 unsigned Population::bestIndex() const
00530 {
00531     RANGE_CHECK(size() > 0)
00532 
00533     unsigned ind = 0;
00534 
00535     if (ascending) {
00536         for (unsigned i = 1; i < size(); i++)
00537             if ((*this)[ i ].fitness < (*this)[ ind ].fitness)
00538                 ind = i;
00539     }
00540     else {
00541         for (unsigned i = 1; i < size(); i++)
00542             if ((*this)[ i ].fitness > (*this)[ ind ].fitness)
00543                 ind = i;
00544     }
00545 
00546     return ind;
00547 }
00548 
00549 //===========================================================================
00550 
00551 unsigned Population::worstIndex() const
00552 {
00553     RANGE_CHECK(size() > 0)
00554 
00555     unsigned ind = size() - 1;
00556 
00557     if (ascending) {
00558         for (unsigned i = size() - 1; i--;)
00559             if ((*this)[ i ].fitness > (*this)[ ind ].fitness)
00560                 ind = i;
00561     }
00562     else {
00563         for (unsigned i = size() - 1; i--;)
00564             if ((*this)[ i ].fitness < (*this)[ ind ].fitness)
00565                 ind = i;
00566     }
00567 
00568     return ind;
00569 }
00570 
00571 //===========================================================================
00572 
00573 void Population::selectInit()
00574 {
00575     for (unsigned i = size(); i--;) {
00576         (*this)[ i ].numCopies = 0;
00577         (*this)[ i ].elitist   = false;
00578     }
00579 }
00580 
00581 void Population::selectElitists(Population& parents,
00582                                 unsigned numElitists)
00583 {
00584     if (numElitists) {
00585         unsigned   i;
00586         double     s;
00587         Population pop(*this);
00588         vector< Individual * > indvec(pop.size() + parents.size());
00589 
00590         //
00591         // sort populations
00592         //
00593         std::copy(pop.begin(), pop.end(), indvec.begin());
00594         std::copy(parents.begin(), parents.end(), indvec.begin() + pop.size());
00595         sortIndividuals(indvec);
00596 
00597         //
00598         // copy elitists and correct selection probabilities
00599         //
00600         for (i = 0; i < size() && i < numElitists; i++) {
00601             indvec[ i ]->selProb -= Shark::min(indvec[i]->selProb, 1. / size());
00602             indvec[ i ]->numCopies++;
00603             indvec[ i ]->elitist = true;
00604             (*this)[ i ] = *indvec[ i ];
00605         }
00606 
00607         s = 0;
00608         for (i = 0; i < parents.size(); i++)
00609             s += parents[ i ].selProb;
00610         if (s > 0)
00611             for (i = 0; i < parents.size(); i++)
00612                 parents[ i ].selProb /= s;
00613     }
00614 }
00615 
00616 //===========================================================================
00617 //
00618 // stochastic universal sampling according to Baker,87
00619 //
00620 void Population::selectRouletteWheel(Population& parents,
00621                                      unsigned numElitists)
00622 {
00623     unsigned i, j;
00624     double   p, r, s;
00625 
00626     if (spinOnce) {
00627         //
00628         // spin the wheel one time, derandomized variant
00629         // (stochastic remainder method according to Baker '87)
00630         //
00631         p = size() - numElitists;
00632         r = Rng::uni(0, 1);
00633         s = 0.;
00634         for (i = numElitists, j = 0;
00635                 i < size() && j < parents.size(); j++) {
00636             s += p * parents[ j ].selProb;
00637             while (s > r && i < size()) {
00638                 parents[ j ].numCopies++;
00639                 (*this)[ i++ ] = parents[ j ];
00640                 r++;
00641             }
00642         }
00643     }
00644     else {
00645         //
00646         // full stochastic method
00647         //
00648         for (i = numElitists; i < size();) {
00649             r = Rng::uni(0, 1);
00650             s = 0.;
00651             for (j = 0;
00652                     j < parents.size() &&
00653                     r >= (p = parents[ j ].selProb) + s;
00654                     s += p, j++);
00655             RANGE_CHECK(j < parents.size())
00656             parents[ j ].numCopies++;
00657             (*this)[ i++ ] = parents[ j ];
00658         }
00659     }
00660 }
00661 
00662 //===========================================================================
00663 //
00664 // Standard: Die mu besten Individuen aus parents werden in die aktuelle
00665 //           Population uebernommen
00666 // Elitist : Die no_elitists besten Individuen aus parents und der aktuellen
00667 //           Population werden uebernommen und der Rest stammt aus parents,
00668 //           aber keine doppelten aus der Elite.
00669 //
00670 void Population::selectMuLambda(Population& parents,
00671                                 unsigned numElitists)
00672 {
00673     unsigned i, j;
00674 
00675     //
00676     // clear number of copies and select elitists
00677     //
00678     parents.selectInit();
00679     selectElitists(parents, numElitists);
00680 
00681     //
00682     // sort parents (only pointers)
00683     //
00684     vector< Individual * > indvec(parents);
00685     sortIndividuals(indvec);
00686 
00687     for (i = numElitists, j = 0;
00688             i < size() && j < indvec.size(); j++) {
00689         if (! indvec[ j ]->elitist) {
00690             indvec[ j ]->numCopies++;
00691             (*this)[ i++ ] = *indvec[ j ];
00692         }
00693     }
00694 
00695     //
00696     // fill remaining slots with the last/worst individual
00697     //
00698     while (i < size()) {
00699         indvec[ j-1 ]->numCopies++;
00700         (*this)[ i++ ] = *indvec[ j-1 ];
00701     }
00702 }
00703 
00704 //===========================================================================
00705 //
00706 //
00707 //
00708 void Population::selectMuLambdaKappa(Population& parents,
00709                                      unsigned lifespan,
00710                                      unsigned adolescence)
00711 {
00712     unsigned i, j;
00713     Population pop(*this);
00714     vector< Individual * > indvec;
00715 
00716     //
00717     // clear number of copies
00718     //
00719     parents.selectInit();
00720 
00721     //
00722     // copy individuals, discard old ones, save young ones
00723     //
00724     for (i = j = 0; i < size() && j < pop.size(); ++j) {
00725         //
00726         // if individual is a youngster copy it directly to next generation
00727         //
00728         if (pop[ j ].age < adolescence) {
00729             pop[ j ].numCopies++;
00730             (*this)[ i++ ] = pop[ j ];
00731             //
00732             // otherwise check whether individual exceeds its lifespan
00733             //
00734         }
00735         else if (pop[ j ].age < lifespan)
00736             indvec.push_back(&pop[ j ]);
00737     }
00738 
00739     //
00740     // same procedure for the parent population
00741     //
00742     for (j = 0; i < size() && j < parents.size(); ++j) {
00743         if (parents[ j ].age < adolescence) {
00744             parents[ j ].numCopies++;
00745             (*this)[ i++ ] = parents[ j ];
00746         }
00747         else if (parents[ j ].age < lifespan)
00748             indvec.push_back(&parents[ j ]);
00749     }
00750 
00751     //
00752     // sort remaining individuals
00753     //
00754     sortIndividuals(indvec);
00755 
00756     //
00757     // copy the best individuals to the current population
00758     //
00759     for (j = 0; i < size() && j < indvec.size(); ++j) {
00760         indvec[ j ]->numCopies++;
00761         (*this)[ i++ ] = *indvec[ j ];
00762     }
00763 
00764     //
00765     // fill remaining slots with old individuals
00766     //
00767     pop.sort();
00768     for (j = 0; i < size() && j < pop.size(); ++j) {
00769         pop[ j ].numCopies++;
00770         (*this)[ i++ ] = pop[ j ];
00771     }
00772 
00773     //
00774     // increment age of all individuals
00775     //
00776     incAge();
00777 }
00778 
00779 
00780 //===========================================================================
00781 
00782 //
00783 // added by Stefan Wiegand at 20.11.2002
00784 //
00785 
00786 int Population::pvm_pkpop()
00787 {
00788     //cout << "\tPopulation_pk" << endl;
00789 
00790     unsigned i;
00791 
00792     unsigned *s = new unsigned;
00793     *s = this->size();
00794     pvm_pkuint(s, 1, 1);
00795     delete s;
00796 
00797     for (i = 0; i < this->size(); i++)
00798         ((*this)[i]).pvm_pkind();
00799 
00800     unsigned *u = new unsigned[4];
00801     u[0] = index;
00802     u[1] = subPop;
00803     u[2] = ascending;
00804     u[3] = spinOnce;
00805     pvm_pkuint(u, 4, 1);
00806     delete[] u;
00807 
00808     return 1;
00809 }
00810 
00811 int Population::pvm_upkpop()
00812 {
00813     // cout << "\tPopulation_upk" << endl;
00814 
00815     unsigned i;
00816 
00817     unsigned *s = new unsigned;
00818     pvm_upkuint(s, 1, 1);
00819     if (this->size() != *s) {
00820       throw SHARKEXCEPTION("EALib/Population.cpp: the population which has called pvm_upkpop() is of unexpected size!\nPlease initialize this population prototypically.");
00821     }
00822     delete s;
00823 
00824     for (i = 0; i < this->size(); i++)
00825         ((*this)[i]).pvm_upkind();
00826 
00827     unsigned *u   = new unsigned[4];
00828     pvm_upkuint(u, 4, 1)     ;
00829     index     = u[0]       ;
00830     subPop    = (u[1] != 0);
00831     ascending = (u[2] != 0);
00832     spinOnce  = (u[3] != 0);
00833     delete[] u;
00834 
00835     return 1;
00836 }
00837 
00838 
00839 
00840 //===========================================================================
00841 //
00842 // linear dynamic scaling
00843 //
00844 //
00845 void Population::linearDynamicScaling(vector< double >& window,
00846                                       unsigned long t)
00847 {
00848     unsigned omega;
00849     double   f;
00850 
00851     omega = window.size();
00852 
00853     if (t == 0) {   // fill scaling window
00854         f = worst().fitness;
00855         for (unsigned i = omega; i--; window[ i ] = f);
00856     }
00857     else {
00858         f = window[(t + omega) % omega ];
00859         window[ t % omega ] = worst().fitness;
00860     }
00861 
00862     if (ascending)
00863         for (unsigned i = size(); i--;)
00864             (*this)[ i ].scaledFitness = f - (*this)[ i ].fitness;
00865     else
00866         for (unsigned i = size(); i--;)
00867             (*this)[ i ].scaledFitness = (*this)[ i ].fitness - f;
00868 }
00869 
00870 //===========================================================================
00871 //
00872 // Standard: Proportionale Selektion, die Fitnesswerte muessen positiv sein
00873 // Elitist : Die no_elitists besten Individuen aus parents und der aktuellen
00874 //           Population werden uebernommen und der Rest stammt aus parents
00875 //
00876 // stochastic universal sampling according to Baker,87
00877 //
00878 void Population::selectProportional(Population& parents,
00879                                     unsigned numElitists)
00880 {
00881     unsigned i;
00882     double   s, t;
00883 
00884     //
00885     // clear number of copies and select elitists
00886     //
00887     parents.selectInit();
00888     selectElitists(parents, numElitists);
00889 
00890     //
00891     // selection probabilities are proportional to the (scaled) fitness
00892     //
00893     for (t = 0., i = 0; i < parents.size(); i++)
00894         if (parents[ i ].scaledFitness < t)
00895             t = parents[ i ].scaledFitness;
00896     for (s = 0., i = 0; i < parents.size(); i++)
00897         s += (parents[ i ].scaledFitness -= t);
00898     for (i = 0; i < parents.size(); i++)
00899         parents[ i ].selProb = parents[ i ].scaledFitness / s;
00900 
00901     //
00902     // select individuals by roulette wheel selection
00903     //
00904     selectRouletteWheel(parents, numElitists);
00905 }
00906 
00907 //===========================================================================
00908 //
00909 // Standard: Proportionale Selektion, die Fitnesswerte muessen positiv sein
00910 //
00911 // stochastic universal sampling according to Baker,87
00912 //
00913 Individual& Population::selectOneIndividual()
00914 {
00915     unsigned i;
00916     double   p, r, s, t;
00917 
00918     //
00919     // selection probabilities are proportional to the (scaled) fitness
00920     //
00921     for (t = 0., i = 0; i < size(); ++i)
00922         if ((*this)[ i ].scaledFitness < t)
00923             t = (*this)[ i ].scaledFitness;
00924     for (s = 0., i = 0; i < size(); ++i)
00925         s += ((*this)[ i ].scaledFitness -= t);
00926     for (i = 0; i < size(); i++)
00927         (*this)[ i ].selProb = (*this)[ i ].scaledFitness / s;
00928 
00929     //
00930     // select individuals by roulette wheel selection
00931     // (full stochastic method)
00932     //
00933     r = Rng::uni(0, 1);
00934     s = 0.;
00935     for (i = 0; i < size() &&
00936             r > (p = (*this)[ i ].selProb) + s;
00937             s += p, ++i);
00938     (*this)[ i ].numCopies++;
00939     return (*this)[ i ];
00940 }
00941 
00942 //===========================================================================
00943 //
00944 // stochastic universal sampling according to Baker,87
00945 //
00946 void Population::selectLinearRanking(Population& parents,
00947                                      double etaMax,
00948                                      unsigned numElitists)
00949 {
00950     if (size() == 0 || parents.size() == 0)
00951         return;
00952     else if (parents.size() == 1)
00953         //
00954         // if the parent population has only one individual it
00955         // receives selection probability 1
00956         //
00957         parents[ 0 ].selProb = 1;
00958     else {
00959         //
00960         // sort parents (only pointers)
00961         //
00962         vector< Individual * > indvec(parents);
00963         sortIndividuals(indvec);
00964 
00965         //
00966         // selection probabilities
00967         //
00968         double a = 2 * (etaMax - 1) / (indvec.size() - 1);
00969         for (unsigned i = 0; i < indvec.size(); i++)
00970             indvec[ i ]->selProb = (etaMax - a * i) / indvec.size();
00971     }
00972 
00973     //
00974     // clear number of copies and select elitists
00975     //
00976     parents.selectInit();
00977     selectElitists(parents, numElitists);
00978 
00979     //
00980     // select individuals by roulette wheel selection
00981     //
00982     selectRouletteWheel(parents, numElitists);
00983 }
00984 
00985 //===========================================================================
00986 //
00987 // numberOfIndividuals == parents.numberOfIndividuals => random walk
00988 //
00989 //
00990 void Population::selectUniformRanking(Population& parents,
00991                                       unsigned numElitists)
00992 {
00993     //
00994     // selection probabilities
00995     //
00996     double p = 1. / parents.size();
00997     for (unsigned i = parents.size(); i--;)
00998         parents[ i ].selProb = p;
00999 
01000     //
01001     // clear number of copies and select elitists
01002     //
01003     parents.selectInit();
01004     selectElitists(parents, numElitists);
01005 
01006     //
01007     // select individuals by roulette wheel selection
01008     //
01009     selectRouletteWheel(parents, numElitists);
01010 }
01011 
01012 //===========================================================================
01013 //
01014 // no ( real ) correction for elitists
01015 //
01016 void Population::selectTournament(Population& parents,
01017                                   unsigned q,
01018                                   unsigned numElitists)
01019 {
01020     unsigned i, j;
01021     Individual* ind;
01022 
01023     //
01024     // clear number of copies and select elitists
01025     //
01026     parents.selectInit();
01027     selectElitists(parents, numElitists);
01028 
01029     //
01030     // clear number of copies once again
01031     //
01032     for (i = parents.size(); i--;)
01033         parents[ i ].numCopies = 0;
01034 
01035     //
01036     // loop for all individuals to be replaced
01037     //
01038     for (i = numElitists; i < size();) {
01039         //
01040         // first candidate for tournament
01041         //
01042         ind = &parents.random();
01043 
01044         //
01045         // loop for tournament size - 1
01046         //
01047         for (j = 1; j < q; j++)
01048             //
01049             // select competitor and save the winner
01050             //
01051             ind = &parents.best(*ind, parents.random());
01052 
01053         //
01054         // copy winner of tournament to next generation
01055         // if an elitist is selected the first time then skip it
01056         //
01057         if (! ind->elitist || ind->numCopies > 0)
01058             (*this)[ i++ ] = *ind;
01059         ind->numCopies++;
01060     }
01061 }
01062 
01063 //===========================================================================
01064 //
01065 // no ( real ) correction for elitists
01066 //
01067 void Population::selectLinearRankingWhitley(Population& parents,
01068         double a,
01069         unsigned numElitists)
01070 {
01071     unsigned i, j;
01072 
01073     //
01074     // clear number of copies and select elitists
01075     //
01076     parents.selectInit();
01077     selectElitists(parents, numElitists);
01078 
01079     //
01080     // clear number of copies once again
01081     //
01082     for (i = parents.size(); i--;)
01083         parents[ i ].numCopies = 0;
01084 
01085     //
01086     // sort parents (only pointers)
01087     //
01088     vector< Individual * > indvec(parents);
01089     sortIndividuals(indvec);
01090 
01091     double b = 2 * (a - 1);
01092     double c = a * a;
01093     double d = 2 * b;
01094 
01095     for (i = numElitists; i < size();) {
01096         j = unsigned(indvec.size() *
01097                      (a - sqrt(c - Rng::uni(0, d))) / b);
01098 
01099         //
01100         // if an elitist is selected the first time then skip it
01101         //
01102         if (! indvec[ j ]->elitist || indvec[ j ]->numCopies > 0)
01103             (*this)[ i++ ] = *indvec[ j ];
01104         indvec[ j ]->numCopies++;
01105     }
01106 }
01107 
01108 //===========================================================================
01109 //
01110 // EP-style Tournament Selection according to D. B. Fogel
01111 //
01112 bool Population::greaterScoreAscending(Individual*const& i1, Individual*const&
01113                                        i2)
01114 {
01115     if (i1->scaledFitness > i2->scaledFitness) return true;
01116     if (i1->scaledFitness < i2->scaledFitness) return false;
01117     if (i1->fitness < i2->fitness) return true;
01118     return false;
01119 }
01120 
01121 bool Population::greaterScoreDescending(Individual*const& i1, Individual*const&
01122                                         i2)
01123 {
01124     if (i1->scaledFitness > i2->scaledFitness) return true;
01125     if (i1->scaledFitness < i2->scaledFitness) return false;
01126     if (i1->fitness > i2->fitness) return true;
01127     return false;
01128 }
01129 
01130 //  void Population::selectEPTournament( Population& parents,
01131 //                                       unsigned q )
01132 //  {
01133 //    unsigned opponent;
01134 
01135 //    Population pop( *this );
01136 //    pop.append( parents );
01137 
01138 //    // perform tournament
01139 //    for( unsigned i = 0; i < pop.size(); i++ ) {
01140 //      //cout << pop[ i ].scaledFitness << " " << pop[ i ].fitnessValue() << endl;
01141 //      pop[ i ].scaledFitness = 0;
01142 //      for( unsigned j = 0; j < q; j++ ) {
01143 //        opponent = Rng::discrete( 0, pop.size( ) - 1 );
01144 //        if( ascending ) {
01145 //          if( pop[ i ].fitnessValue( ) <= pop[ opponent ].fitnessValue( ) )
01146 //            pop[ i ].scaledFitness++;
01147 //        } else {
01148 //          if( pop[ i ].fitnessValue( ) >= pop[ opponent ].fitnessValue( ) )
01149 //            pop[ i ].scaledFitness++;
01150 //        }
01151 //      }
01152 //    }
01153 
01154 //    // sort parents and offspring
01155 //    vector< Individual * > indvec( pop );
01156 //    std::sort( indvec.begin( ), indvec.end( ),
01157 //               ascending
01158 //             ? Population::greaterScoreAscending
01159 //             : Population::greaterScoreDescending );
01160 //    for( unsigned j = 0; j < size(); j++ )
01161 //      ( *this )[ j ] = *indvec[ j ];
01162 //    /*
01163 //    for( unsigned j = 0; j < pop.size( ); j++ )
01164 //      cout << indvec[ j ]->fitnessValue( ) << " " << indvec[ j ]->scaledFitness << endl;
01165 //    */
01166 //  }
01167 
01168 void Population::selectEPTournament(Population& offspring,
01169                                     unsigned q)
01170 {
01171     Population pop(*this);
01172 
01173     unsigned i;
01174     unsigned opponent;
01175 
01176     unsigned poolSize = this->size() + offspring.size();
01177 
01178     vector< Individual * > indvec(poolSize);
01179 
01180     for (i = 0; i < this->size(); i++) indvec[i] = &(pop[ i ]);
01181     for (i = 0; i < offspring.size(); i++) indvec[this->size() + i] = &(offspring[ i ]);
01182 
01183     // perform tournament
01184     for (i = 0; i < poolSize; i++) {
01185         indvec[ i ]->scaledFitness = 0;
01186         for (unsigned j = 0; j < q; j++) {
01187             opponent = Rng::discrete(0, poolSize - 1);
01188             if (ascending) {
01189                 if (indvec[i]->fitnessValue() <= indvec[ opponent ]->fitnessValue())
01190                     indvec[ i ]->scaledFitness++;
01191             }
01192             else {
01193                 if (indvec[ i ]->fitnessValue() >= indvec[ opponent ]->fitnessValue())
01194                     indvec[ i ]->scaledFitness++;
01195             }
01196         }
01197     }
01198 
01199     // sort parents and offspring
01200     std::sort(indvec.begin(), indvec.end(),
01201               ascending
01202               ? Population::greaterScoreAscending
01203               : Population::greaterScoreDescending);
01204 
01205     for (unsigned j = 0; j < size(); j++)
01206         (*this)[ j ] = *indvec[ j ];
01207 }
01208 
01209 //===========================================================================
01210 
01211 /*
01212 void replaceUnconditional( Population& pop )
01213 {
01214     Index index( 0, numElements-1 );
01215     index.permute( );
01216 
01217     for( unsigned i = Shark::min( numElements, pop.numElements ); i--; )
01218         *elements[ index[ i ] ] = *pop.elements[ i ];
01219 }
01220 
01221 //===========================================================================
01222 
01223 void replaceConditional( Population& pop )
01224 {
01225     Index index( 0, numElements-1 );
01226     index.permute( );
01227 
01228     for( unsigned i = Shark::min( numElements, pop.numElements ); i--; )
01229         *elements[ index[ i ] ] = best( *elements[ index[ i ] ],
01230                         *pop.elements[ i ] );
01231 }
01232 */
01233 
01234 //===========================================================================
01235 
01236 double Population::minFitness() const
01237 {
01238     double f = 0;
01239 
01240     if (size()) {
01241         f = (*this)[ 0 ].fitness;
01242         for (unsigned i = 1; i < size(); i++)
01243             f = Shark::min(f, (*this)[ i ].fitness);
01244     }
01245 
01246     return f;
01247 }
01248 
01249 //===========================================================================
01250 
01251 double Population::maxFitness() const
01252 {
01253     double f = 0;
01254 
01255     if (size()) {
01256         f = (*this)[ 0 ].fitness;
01257         for (unsigned i = 1; i < size(); i++)
01258             f = Shark::max(f, (*this)[ i ].fitness);
01259     }
01260 
01261     return f;
01262 }
01263 
01264 //===========================================================================
01265 
01266 double Population::meanFitness() const
01267 {
01268     double f = 0;
01269 
01270     if (size()) {
01271         for (unsigned i = size(); i--;)
01272             f += (*this)[ i ].fitness;
01273         f /= size();
01274     }
01275 
01276     return f;
01277 }
01278 
01279 //===========================================================================
01280 
01281 double Population::stdDevFitness() const
01282 {
01283     double m = 0;
01284     double s = 0;
01285 
01286     if (size()) {
01287         for (unsigned i = size(); i--;) {
01288             m += (*this)[ i ].fitness;
01289             s += (*this)[ i ].fitness * (*this)[ i ].fitness;
01290         }
01291         m /= size();
01292         s /= size();
01293         s -= m * m;
01294     }
01295 
01296     //
01297     // due to rounding problems the value of 's' may be negative
01298     // in this case 's' is supposed to be zero
01299     //
01300     return s > 0 ? sqrt(s) : 0;
01301 }
01302 
01303 //===========================================================================
01304 
01305 void Population::setAge(unsigned a)
01306 {
01307     for (unsigned i = size(); i--;)
01308         (*this)[ i ].setAge(a);
01309 }
01310 
01311 void Population::incAge()
01312 {
01313     for (unsigned i = size(); i--;)
01314         (*this)[ i ].incAge();
01315 }
01316 
01317 //===========================================================================
01318 
01319 bool Population::operator == (const Population& pop) const
01320 {
01321     if (size() == pop.size()) {
01322         for (unsigned i = 0; i < size(); ++i)
01323             if ((*this)[ i ] != pop[ i ]) return false;
01324 
01325         return index     == pop.index     &&
01326                subPop    == pop.subPop    &&
01327                ascending == pop.ascending &&
01328                spinOnce  == pop.spinOnce;
01329     }
01330 
01331     return false;
01332 }
01333 
01334 bool Population::operator < (const Population& pop) const
01335 {
01336     if (size() == pop.size()) {
01337         bool less = false;
01338 
01339         for (unsigned i = 0; i < size(); ++i)
01340             if (pop[ i ] < (*this)[ i ])
01341                 return false;
01342             else if (! less && (*this)[ i ] < pop[ i ])
01343                 less = true;
01344 
01345         return less/*                     &&
01346                        index     <= pop.index     &&
01347                        subPop    <= pop.subPop    &&
01348                        ascending <= pop.ascending &&
01349                        spinOnce  <= pop.spinOnce*/;
01350     }
01351 
01352     return size() < pop.size();
01353 }
01354 
01355 
01356 //===========================================================================
01357 
  • Shark Main Page
  • Array
  • Rng
  • LinAlg
  • FileUtil
  • EALib
  • MOO-EALib
  • ReClaM
  • Fuzzy
  • Mixture
  • Tutorials
  • FAQ