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: */