00001
00025 #include <magic/mstream.h>
00026 #include <magic/mclass.h>
00027
00028 #include "nhp/gaenvrnmt.h"
00029 #include "nhp/individual.h"
00030 #include "nhp/genes.h"
00031 #include "nhp/population.h"
00032 #include "nhp/selection.h"
00033
00034 impl_dynamic (Individual, {Comparable});
00035
00037
00038
00039
00040
00041
00042
00043
00045
00046 Individual::Individual () {
00047 mpSelector = new Selector ();
00048 incarnate (false);
00049 }
00050
00051 Individual::Individual (const Individual& prototype) : genome (prototype.genome) {
00052 mpSelector = new Selector (*prototype.mpSelector);
00053 incarnate (false);
00054 }
00055
00056 Individual::Individual (const Genome& genotype) : genome (genotype) {
00057 mpSelector = new Selector ();
00058 incarnate (false);
00059 }
00060
00061 Individual::~Individual () {
00062 delete mpSelector;
00063 }
00064
00065 void Individual::addGenesTo (Genome& g, const StringMap& params) {
00066 Selector::addGenesTo (g, params);
00067 }
00068
00069 void Individual::incarnate (bool doinit) {
00070 fitness = 0.0;
00071 avg_over = 0;
00072 age = 0;
00073
00074 mFeatures.empty ();
00075
00076
00077 if (doinit) {
00078
00079 mpSelector->read (genome);
00080
00081
00082
00083 genome.execute (GeneticMsg ("init", *this));
00084 }
00085 }
00086
00087 void Individual::grow_older () {
00088
00089 age++;
00090 }
00091
00092
00103 double Individual::evaluate (EAEnvironment& envr,
00104 bool force )
00105 {
00106
00107 while (avg_over < envr.evals() || force) {
00108 double measured_fitness = envr.evaluate (*this);
00109
00110
00111 fitness = (fitness*avg_over + measured_fitness) / (++avg_over);
00112
00113 if (avg_over >= envr.evals() && force)
00114 break;
00115 }
00116
00117
00118 grow_older ();
00119
00120 return fitness;
00121 }
00122
00123 void Individual::joinfitness (const Individual& other) {
00124 if (avg_over>0 || other.avg_over>0)
00125 fitness = (fitness*avg_over + other.fitness*other.avg_over) / (avg_over+other.avg_over);
00126
00127 avg_over += other.avg_over;
00128
00129
00130 for (int k=0; k<other.genome.getkings(); k++)
00131 genome.addking ();
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141 int Individual::compare (const Comparable& other) const {
00142 const Individual* o = static_cast <const Individual*> (&other);
00143 if (fitness < o->fitness)
00144 return -1;
00145 else
00146 if (fitness == o->fitness)
00147 return 0;
00148 else
00149 return 1;
00150 }
00151
00152 void Individual::recombine (const Individual& a, const Individual& b) {
00153 genome.recombine (a.genome, b.genome);
00154 incarnate (false);
00155 }
00156
00157 bool Individual::pointMutate (const MutationRate& k) {
00158
00159 bool mut = genome.pointMutate (k);
00160
00161
00162 if (mut)
00163 incarnate (false);
00164
00165 return mut;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174 void Individual::print (TextOStream& out) const
00175 {
00176 FUNCTION_BEGIN;
00177
00178 if (out[PRINT_CLASSNAMES])
00179 out << "Indv";
00180 out << '{';
00181
00182 if (out[PRINT_NAMES])
00183 out << "ftn=";
00184
00185 if (fitness>0.0)
00186 out.printf ("%01.3f, ", fitness);
00187 else
00188 out << "[UNKN], ";
00189
00190 if (out[PRINT_NAMES])
00191 out << "age=";
00192
00193 out.printf ("%03d, ", getage ());
00194
00195
00196 failtrace (genome.print (out));
00197
00198 out << '}';
00199
00200 FUNCTION_END;
00201 }
00202
00203 DataOStream& Individual::operator>> (DataOStream& out) const {
00204 out.name ("fitness") << fitness;
00205 out.name ("avg_over") << avg_over;
00206 out.name ("age") << age;
00207 out.name ("genome") << genome;
00208
00209 return out;
00210 }
00211
00212 void Individual::check () const {
00213 forMap(String,Object,mFeatures,i) {
00214 ASSERT (!isempty(i.key()));
00215 i.value().check ();
00216 }
00217
00218 ASSERT (avg_over>=0);
00219 ASSERT (age>=0);
00220 genome.check ();
00221 }
00222
00223 void Individual::setSelector (const SelectionPrms& templ) {
00224 delete mpSelector;
00225 mpSelector = new Selector (templ);
00226 }
00227