00001
00020 #include "populationreal.h"
00021 #include "random.h"
00022 #include "initind.h"
00023 #include "define.h"
00024 #include <algorithm>
00025 #include <iostream>
00026 #include <cassert>
00027
00028 using std::sort;
00029 using namespace realea;
00030 using realea::internal::SimpleInitInd;
00031 using realea::internal::UniformInitInd;
00032
00033 void PopulationReal::setObserver(PopulationObserver *observer) {
00034 m_observers.push_back(observer);
00035 }
00036
00037 PopulationReal::PopulationReal(Random *random, unsigned int max, unsigned int pob):
00038 m_aditionalsize(max), m_size(pob), m_individuals(),
00039 m_random(random),
00040 m_knownbest(false), m_knownworst(false), m_observers() {
00041 m_individuals.reserve(m_aditionalsize);
00042
00043 m_initInd = new UniformInitInd(m_random);
00044 }
00045
00046 PopulationReal::~PopulationReal(void) {
00047 vector<tIndividualRealPtr>::iterator item;
00048 deque<PopulationObserver*>::iterator observer;
00049
00050
00051 for (item = m_individuals.begin(); item != m_individuals.end(); ++item) {
00052 delete (*item);
00053 }
00054
00055 m_observers.clear();
00056
00057 if (m_initInd) {
00058 delete m_initInd;
00059 }
00060 }
00061
00062 template<class T>
00063 void call_reset(T *elem) {
00064 elem->reset();
00065 }
00066
00067 void PopulationReal::reset(DomainRealPtr domain, int posi) {
00068 unsigned size = m_individuals.size();
00069 tIndividualRealPtr old=NULL;
00070
00071 m_knownbest = m_knownworst = false;
00072
00073 if (posi >= 0) {
00074 old = m_individuals[posi];
00075 m_individuals[posi] = NULL;
00076 }
00077
00078 for (int i = 0; i < size; ++i) {
00079 if (m_individuals[i]) {
00080 delete m_individuals[i];
00081 m_individuals[i] = NULL;
00082 }
00083 }
00084 if (!m_individuals.empty()) {
00085 m_individuals.erase(m_individuals.begin(), m_individuals.end());
00086 }
00087
00088 if (old != NULL) {
00089 m_initInd->resetBest(domain, old->sol(), m_size);
00090 }
00091 else {
00092 m_initInd->reset(domain, m_size);
00093 }
00094
00095 for (unsigned i = 0; i < m_size; ++i) {
00096 tChromosomeReal crom;
00097
00098 if (i != posi) {
00099 m_initInd->createInd(domain, crom);
00100 tIndividualReal *individual = getInstance(crom);
00101 individual->setId(i);
00102 m_individuals.push_back(individual);
00103 }
00104 else {
00105 m_individuals.push_back(old);
00106 }
00107 }
00108
00109 resetObservers();
00110 }
00111
00112 tIndividualReal *PopulationReal::getInstance(tChromosomeReal &crom) {
00113 return new tIndividualReal(crom);
00114 }
00115
00116 tIndividualReal *PopulationReal::getInstance(tChromosomeReal &crom, tFitness fitness) {
00117 return new tIndividualReal(crom, fitness);
00118 }
00119
00120 bool isNull(tIndividualReal *ind) {
00121 return (ind==NULL);
00122 }
00123
00124 bool PopulationReal::thereNull(void) {
00125 return false;
00126 vector<tIndividualReal*>::iterator posNull = find_if(m_individuals.begin(), m_individuals.end(), isNull);
00127
00128 return (posNull != m_individuals.end());
00129 }
00130
00131 void PopulationReal::updateObservers(void) {
00132 vector<tIndividualReal*>::iterator posind;
00133 deque<PopulationObserver*>::iterator observer;
00134 tIndividualRealPtr individual;
00135 unsigned newid, oldid;
00136
00137 for (newid = 0, posind = m_individuals.begin(); posind != m_individuals.end(); ++posind) {
00138 for (observer = m_observers.begin(); observer != m_observers.end(); ++observer) {
00139 individual = *posind;
00140 oldid = individual->getId();
00141 newid++;
00142 individual->setId(newid);
00143 (*observer)->changeId(oldid, newid);
00144 }
00145
00146 }
00147 }
00148
00154 void PopulationReal::notifyObservers(unsigned id) {
00155 deque<PopulationObserver*>::iterator observer;
00156
00157 for (observer = m_observers.begin(); observer != m_observers.end(); ++observer) {
00158 (*observer)->notifyChange(id);
00159 }
00160 }
00161
00167 void PopulationReal::resetObservers(void) {
00168 deque<PopulationObserver*>::iterator observer;
00169 for (observer = m_observers.begin(); observer != m_observers.end(); ++observer) {
00170 (*observer)->reset();
00171 }
00172 }
00173
00174
00175
00176 void PopulationReal::sort(void) {
00177 tIndividualReal::sort(m_individuals);
00178
00179 m_knownbest = m_knownworst = true;
00180 m_best = 0;
00181 m_worst = m_individuals.size()-1;
00182
00183 if (thereNull()) {
00184 throw new string("PopulationReal::sort,there is null");
00185 }
00186
00187 }
00188
00189 bool isNotEval(tIndividualReal *ind) {
00190 return (!ind->isEval());
00191 }
00192
00193 void PopulationReal::removePending(void) {
00194 if (m_individuals.empty())
00195 return;
00196
00197
00198 vector<tIndividualReal*>::iterator beginNotEval = find_if(m_individuals.begin(), m_individuals.end(), isNotEval);
00199
00200
00201 if ((beginNotEval != m_individuals.end())) {
00202 remove(beginNotEval-m_individuals.begin(), m_individuals.size());
00203 }
00204 }
00205
00206 void PopulationReal::remove(unsigned begin, unsigned end) {
00207 assert(begin <= end);
00208 assert(end <= m_individuals.size());
00209
00210 for (unsigned i = begin; i < end; i++) {
00211 delete m_individuals[i];
00212 m_individuals[i]=NULL;
00213 }
00214
00215 vector<tIndividualReal*>::iterator base = m_individuals.begin();
00216 m_individuals.erase(base+begin, base+end);
00217 }
00218
00219 void PopulationReal::removeWorses(void) {
00220 sort();
00221 removePending();
00222 unsigned size = m_individuals.size();
00223
00224 if (!m_individuals.empty() && size > m_size) {
00225 remove(m_size, size);
00226 }
00227
00228 updateObservers();
00229 m_worst = m_individuals.size()-1;
00230 }
00231
00232 void PopulationReal::random(void) {
00233 unsigned int size=m_individuals.size();
00234 int ssize, pos;
00235
00236 if (size == 0)
00237 return;
00238
00239 m_knownbest = m_knownworst = false;
00240
00241 ssize = size;
00242 int *sample = new int[size];
00243 initSample(sample, ssize);
00244
00245 for (unsigned i = 0; i < size; ++i) {
00246 pos = m_random->getSample(sample, &ssize);
00247 swap(m_individuals[i], m_individuals[pos]);
00248 }
00249
00250 delete[] sample;
00251 }
00252
00253 tIndividualReal *PopulationReal::getInd(unsigned int pos) {
00254 assert(pos < m_size);
00255 return m_individuals[pos];
00256 }
00257
00258 void PopulationReal::append(tChromosomeReal &sol, tFitness fitness) {
00259 tIndividualRealPtr ind = getInstance(sol, fitness);
00260 ind->setId(m_individuals.size());
00261 m_individuals.push_back(ind);
00262 }
00263
00264 void PopulationReal::append(tIndividualReal *real) {
00265 if (m_individuals.size() == m_aditionalsize) {
00266 throw new runtime_error("maximum number of elems in population");
00267 }
00268
00269 m_individuals.push_back(real);
00270 m_knownbest = m_knownworst = false;
00271 }
00272
00273 void PopulationReal::change(unsigned int pos, const tChromosomeReal &sol, tFitness fitness) {
00274 assert(pos < m_size);
00275 m_individuals[pos]->change(sol, fitness);
00276 m_knownbest = m_knownworst = false;
00277 }
00278
00279 unsigned PopulationReal::getBest(void) {
00280 assert(!m_individuals.empty());
00281 unsigned int ind;
00282 tIndividualReal *current, *best;
00283 int pos_best;
00284
00285 if (m_knownbest) {
00286 return m_best;
00287 }
00288
00289 pos_best = -1;
00290
00291 best = NULL;
00292 unsigned size = m_individuals.size();
00293
00294 for (ind = 0; ind < size; ++ind) {
00295 current = m_individuals[ind];
00296
00297 if (!current->isEval()) {
00298 continue;
00299 }
00300
00301 if (best == NULL) {
00302 pos_best = ind;
00303 best = current;
00304 }
00305 else if (current->isBetter(best)) {
00306 best = current;
00307 pos_best = ind;
00308 }
00309 }
00310
00311 m_best = pos_best;
00312 m_knownbest = true;
00313 return pos_best;
00314 }
00315
00316 class PopulationSort {
00317 public:
00318 bool operator()(const unsigned &posa, const unsigned &posb) {
00319 if (!m_inds[posa]->isBetter(m_inds[posb]))
00320 return false;
00321 else
00322 return true;
00323 }
00324 PopulationSort(vector<tIndividualRealPtr> &v) : m_inds(v) {}
00325 private:
00326 vector<tIndividualRealPtr> m_inds;
00327 };
00328
00329 vector<unsigned> PopulationReal::getBests(unsigned num) {
00330 vector<unsigned> positions(m_size);
00331 vector<unsigned> bests(num);
00332
00333 for (unsigned i = 0; i < m_individuals.size(); i++) {
00334 positions[i] = i;
00335 }
00336
00337 partial_sort(positions.begin(), positions.begin()+num, positions.end(),
00338 PopulationSort(m_individuals));
00339
00340 copy(positions.begin(), positions.begin()+num, bests.begin());
00341 return bests;
00342 }
00343
00344 unsigned PopulationReal::getWorst(void) {
00345 assert(!m_individuals.empty());
00346 unsigned int ind;
00347 tIndividualReal *current,*worst;
00348 int pos_worst=-1;
00349
00350 if (m_knownworst) {
00351 return m_worst;
00352 }
00353
00354 worst = NULL;
00355 unsigned size = m_individuals.size();
00356
00357 for (ind = 0; ind < size; ++ind) {
00358 current = m_individuals[ind];
00359
00360 if (!current->isEval()) {
00361 continue;
00362 }
00363
00364 if (worst == NULL) {
00365 pos_worst = ind;
00366 worst = current;
00367 }
00368 else if (current->isWorse(worst)) {
00369 worst = current;
00370 pos_worst = ind;
00371 }
00372 }
00373
00374 m_worst = pos_worst;
00375 m_knownworst = true;
00376 return pos_worst;
00377 }
00378
00379
00380 void PopulationReal::eval(IEvalInd *evalInd, unsigned neweval) {
00381 vector<tIndividualRealPtr>::iterator item;
00382 bool maxEval = false;
00383
00384 for (item = m_individuals.begin(); item != m_individuals.end() && !maxEval; ++item) {
00385 if (!(*item)->isEval()) {
00386 neweval -=
00387 evalInd->eval(*item);
00388
00389 if (neweval == 0) {
00390 maxEval = true;
00391 }
00392 }
00393
00394 }
00395 }
00396
00397 unsigned PopulationReal::size(void) {
00398
00399 if (m_individuals.size() < m_size)
00400 return m_individuals.size();
00401 else
00402 return m_size;
00403 }
00404
00405 unsigned PopulationReal::ndim(void) {
00406 assert(m_individuals.size() > 0);
00407 return m_individuals[0]->sol().size();
00408 }
00409
00410 void PopulationReal::replace(unsigned pos, tIndividualRealPtr newind) {
00411 tIndividualRealPtr old = m_individuals[pos];
00412
00413 m_individuals[pos] = newind;
00414 m_individuals[pos]->setId(old->getId());
00415
00416 delete old;
00417
00418 notifyObservers(pos);
00419
00420
00421 if (m_knownbest) {
00422 if (m_best == pos) {
00423 m_knownbest = false;
00424 }
00425 else if (newind->isBetter(m_individuals[m_best])) {
00426 m_best = pos;
00427 }
00428 }
00429
00430 if (m_knownworst) {
00431 if (m_worst == pos) {
00432 m_knownworst = false;
00433 }
00434 else if (newind->isWorse(m_individuals[m_worst])) {
00435 m_worst = pos;
00436 }
00437 }
00438
00439 }
00440
00441 tFitness PopulationReal::getMean(void) {
00442 tFitness sum=0;
00443 unsigned i;
00444 assert(!m_individuals.empty());
00445
00446 for (i = 0; i < m_individuals.size() && m_individuals[i]->isEval(); ++i) {
00447 sum += m_individuals[i]->perf();
00448 }
00449
00450 assert(i == m_individuals.size());
00451 return sum/m_individuals.size();
00452 }
00453
00454 tFitness PopulationReal::getMedian(void) {
00455 vector<unsigned> positions(m_size);
00456 unsigned num, posi;
00457
00458 for (unsigned i = 0; i < m_individuals.size(); i++) {
00459 positions[i] = i;
00460 }
00461
00462 num = m_individuals.size()/2;
00463 partial_sort(positions.begin(), positions.begin()+num, positions.end(),
00464 PopulationSort(m_individuals));
00465
00466 posi = positions[num-1];
00467 return m_individuals[posi]->perf();
00468 }
00469
00470 void PopulationReal::getPercentils(double *percen, unsigned num) {
00471 vector<unsigned> positions(m_size);
00472 unsigned i, posi;
00473
00474 for (i = 0; i < m_individuals.size(); i++) {
00475 positions[i] = i;
00476 }
00477
00478 partial_sort(positions.begin(), positions.end(), positions.end(),
00479 PopulationSort(m_individuals));
00480
00481 percen[0] = m_individuals[getBest()]->perf();
00482
00483 for (i = 1; i <= num; ++i) {
00484 posi = i*m_size/num;
00485 posi = positions[posi-1];
00486 percen[i] = m_individuals[posi]->perf();
00487 }
00488
00489 }