GAPopulation.C

Go to the documentation of this file.
00001 /*!@file GA/GAPopulation.C A population class for genetic algorithm. */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2002   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/GA/GAPopulation.C $
00035 // $Id: GAPopulation.C 6005 2005-11-29 18:49:14Z rjpeters $
00036 //
00037 
00038 #include "GA/GAPopulation.H"
00039 
00040 #include "GA/GAChromosome.H"
00041 #include "Util/Assert.H"
00042 #include "Util/Types.H"
00043 #include <algorithm>
00044 #include <cmath>
00045 #include <cstdlib>
00046 #include <cstring>
00047 #include <istream>
00048 #include <ostream>
00049 
00050 #define MSG_DATA 1
00051 #define MSG_RESULT 2
00052 
00053 GAPopulation::GAPopulation() :
00054   psize(0), csize(0), total_fitness(0.0f), total_linear_fitness(0.0f),
00055   mean_fitness(0.0f), sigma(0.0f), chromosomes(NULL), offspring(NULL)
00056 { }
00057 
00058 GAPopulation::GAPopulation(const int N, const int a) :
00059   psize(0), csize(0), total_fitness(0.0f), total_linear_fitness(0.0f),
00060   mean_fitness(0.0f), sigma(0.0f), chromosomes(NULL), offspring(NULL)
00061 {
00062   init(N, a);
00063 }
00064 
00065 void GAPopulation::resize(const int N, const int a)
00066 {
00067   if (psize)
00068     {
00069       delete [] chromosomes;
00070       delete [] offspring;
00071     }
00072   chromosomes = new GAChromosome[N];
00073   offspring = new GAChromosome[N];
00074   psize = N;
00075   csize = a;
00076 }
00077 
00078 void GAPopulation::init(const int N, const int a)
00079 {
00080   resize(N, a);
00081   for (int i = 0; i < N; i++)
00082     {
00083       chromosomes[i].init(a);
00084       offspring[i].init(a);
00085     }
00086 }
00087 
00088 GAPopulation::~GAPopulation()
00089 {
00090   if (psize)
00091     {
00092       delete [] chromosomes;
00093       delete [] offspring;
00094     }
00095 }
00096 
00097 void GAPopulation::set_chromosome(const int i, const GAChromosome& c)
00098 {
00099   ASSERT(c.get_size() == csize);
00100   chromosomes[i] = c;
00101 }
00102 
00103 GAChromosome GAPopulation::get_chromosome(const int i) const
00104 {
00105   return chromosomes[i];
00106 }
00107 
00108 float GAPopulation::get_mean_fitness() const
00109 {
00110   return mean_fitness;
00111 }
00112 
00113 float GAPopulation::get_sigma() const
00114 {
00115   return sigma;
00116 }
00117 
00118 void GAPopulation::update()
00119 {
00120   for (int i = 0; i < psize; i++)
00121     chromosomes[i] = offspring[i];
00122 }
00123 
00124 void GAPopulation::compute_pop_fitness()
00125 {
00126   total_fitness = 0.0f;
00127   for (int i = 0; i < psize; i++)
00128     total_fitness += chromosomes[i].get_fitness();
00129   mean_fitness = total_fitness / psize;
00130 }
00131 
00132 void GAPopulation::compute_sigma()
00133 {
00134   sigma = 0.0f;
00135   for (int i = 0; i < psize; i++)
00136     {
00137       float x = chromosomes[i].get_fitness() - mean_fitness;
00138       sigma += x * x;
00139     }
00140   sigma /= psize - 1;
00141   sigma = sqrt(sigma);
00142 }
00143 
00144 void GAPopulation::linear_scaling()
00145 {
00146   total_linear_fitness = 0.0f;
00147   for (int i = 0; i < psize; i++)
00148     {
00149       float lf;
00150       if (sigma == 0.0f)
00151         lf = 1.0f;
00152       else
00153         {
00154           float f = chromosomes[i].get_fitness();
00155           if (mean_fitness - f > sigma)
00156             lf = 0.0f;
00157           else
00158             lf = 1.0f + (f - mean_fitness) / (2.0f * sigma);
00159         }
00160       chromosomes[i].set_linear_fitness(lf);
00161       total_linear_fitness += lf;
00162     }
00163 }
00164 
00165 void GAPopulation::selection()
00166 {
00167   int x = rand() % 100;
00168   float spin = (((float) x) / 100.0f) / psize;
00169   int c = -1;
00170   float f = 0.0f;
00171   for (int i = 0; i < psize; i++)
00172     {
00173       while (f < spin)
00174         {
00175           c++;
00176           f += chromosomes[c].get_linear_fitness() / total_linear_fitness;
00177         }
00178       chromosomes[c].add_breeding();
00179       f -= spin;
00180     }
00181 }
00182 
00183 void GAPopulation::crossover()
00184 {
00185   std::sort(chromosomes, chromosomes + psize);
00186   int father = psize - 1;
00187   int mother = psize - 2;
00188   int breed = 0;
00189   while (breed < psize)
00190     {
00191       int cross = (rand() % (csize - 1)) + 1;
00192       for (int i = 0; i < cross; i++)
00193         {
00194           offspring[breed].set_gene(i, chromosomes[father].get_gene(i));
00195           offspring[breed + 1].set_gene(i, chromosomes[mother].get_gene(i));
00196         }
00197       for (int i = cross; i < csize; i++)
00198         {
00199           offspring[breed].set_gene(i, chromosomes[mother].get_gene(i));
00200           offspring[breed + 1].set_gene(i, chromosomes[father].get_gene(i));
00201         }
00202       chromosomes[father].use_breeding();
00203       chromosomes[mother].use_breeding();
00204       breed = breed + 2;
00205       float fb = chromosomes[father].get_breedings();
00206       float mb = chromosomes[mother].get_breedings();
00207       for (int i = mother;
00208            i > 0 && mb < chromosomes[i - 1].get_breedings();
00209            i--)
00210         std::swap(chromosomes[i], chromosomes[i - 1]);
00211       for (int i = father;
00212            i > 0 && fb < chromosomes[i - 1].get_breedings();
00213            i--)
00214         std::swap(chromosomes[i], chromosomes[i - 1]);
00215     }
00216 }
00217 
00218 void GAPopulation::mutate()
00219 {
00220   for (int i = 0; i < psize; i++)
00221     {
00222       int lucky_shot = rand() % csize;
00223       if (lucky_shot == 7)
00224         chromosomes[i].mutation();
00225     }
00226 }
00227 
00228 std::istream& operator>>(std::istream& in, GAPopulation& pop)
00229 {
00230   int ps, cs;
00231   in >> ps >> cs;
00232   pop.resize(ps, cs);
00233   in >> pop.total_fitness >> pop.mean_fitness >> pop.sigma;
00234   in >> pop.total_linear_fitness;
00235   for (int i = 0; i < pop.psize; i++)
00236     {
00237       GAChromosome c;
00238       in >> c;
00239       ASSERT(c.get_size() == pop.csize);
00240       pop.chromosomes[i] = c;
00241     }
00242   return in;
00243 }
00244 
00245 std::ostream& operator<<(std::ostream& out, GAPopulation& pop)
00246 {
00247   out << pop.psize << ' ' << pop.csize << '\n';
00248   out << pop.total_fitness << ' ' << pop.mean_fitness << ' ';
00249   out << pop.sigma << ' ' << pop.total_linear_fitness << '\n';
00250   for (int i = 0; i < pop.psize; i++)
00251     out << pop.chromosomes[i];
00252   return out;
00253 }
00254 
00255 // ######################################################################
00256 /* So things look consistent in everyone's emacs... */
00257 /* Local Variables: */
00258 /* indent-tabs-mode: nil */
00259 /* End: */
Generated on Sun May 8 08:40:39 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3