GAPopulation.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
00257
00258
00259