00001 #include <NLstl_utils.h>
00002
00003 #include "GLLogicError.h"
00004 #include "GLOrganismVector.h"
00005 #include "GLRuntimeError.h"
00006
00018 template<class T>
00019 GLOrganismVector<T>::GLOrganismVector(unsigned init_size,
00020 GLConstants::TSizeLimits size_property,
00021 unsigned max_size):
00022 GLBaseOrganism(),
00023 m_property_bounds(GLConstants::UNBOUNDED_GENES),
00024 m_property_size(size_property)
00025 {
00026 setSizeData(init_size, max_size);
00027 m_storage.resize(init_size);
00028 }
00029
00040 template<class T>
00041 GLOrganismVector<T>::GLOrganismVector(const vector<T>& chromosome,
00042 GLConstants::TSizeLimits size_property,
00043 unsigned max_size):
00044 GLBaseOrganism(),
00045 m_property_bounds(GLConstants::UNBOUNDED_GENES),
00046 m_property_size(size_property),
00047 m_storage(chromosome)
00048 {
00049 setSizeData(chromosome.size(), max_size);
00050 }
00051
00056 template<class T>
00057 GLOrganismVector<T>::GLOrganismVector(const GLOrganismVector<T>& source):
00058 GLBaseOrganism(source)
00059 {
00060 m_gene_max = source.m_gene_max;
00061 m_gene_min = source.m_gene_min;
00062 m_property_bounds = source.m_property_bounds;
00063 m_property_size = source.m_property_size;
00064 m_max_size = source.m_max_size;
00065 m_storage = source.m_storage;
00066 }
00067
00071 template<class T>
00072 GLOrganismVector<T>::~GLOrganismVector()
00073 {
00074
00075 }
00076
00085 template<class T>
00086 void GLOrganismVector<T>::assertCompatibility(const GLBaseOrganism* source,
00087 const string& message) const
00088 {
00089 if (dynamic_cast<const GLOrganismVector<T>*>(source) == NULL)
00090 {
00091 char errormsg[1000];
00092 sprintf(errormsg, "\nGLOrganismVector<T>::assertCompatibility\n"
00093 "%s\n"
00094 "Passed pointer is either NULL or not compatible "
00095 "with this class\n",
00096 message.c_str());
00097 throw GLLogicError(errormsg);
00098 }
00099 }
00100
00108 template<class T>
00109 void GLOrganismVector<T>::copyGeneticData(const GLBaseOrganism *source)
00110 {
00111
00112 assertCompatibility(source, "From: GLOrganismVector<T>::copyGeneticData");
00113 const GLOrganismVector<T> *organism =
00114 dynamic_cast<const GLOrganismVector<T>*> (source);
00115 GLBaseOrganism::copyGeneticData(source);
00116 m_gene_max = organism->m_gene_max;
00117 m_gene_min = organism->m_gene_min;
00118 m_property_bounds = organism->m_property_bounds;
00119 m_property_size = organism->m_property_size;
00120 m_max_size = organism->m_max_size;
00121 m_storage = organism->m_storage;
00122 }
00123
00129 template<class T>
00130 void GLOrganismVector<T>::exchangeGenes(int first, int second)
00131 {
00132 if (!checkIndex(first) || !(checkIndex(second)))
00133 {
00134 char errormsg[1000];
00135 sprintf(errormsg, "\nGLOrganismVector::exhangeGenes\n"
00136 "One of the indices -- first (%i) or second (%i)"
00137 " is outside the organism's size [0, %i)\n",
00138 first, second, getSize());
00139 throw GLLogicError(errormsg);
00140 }
00141 T temp = m_storage[first];
00142 m_storage[first] = m_storage[second];
00143 m_storage[second] = temp;
00144 }
00145
00151 template<class T>
00152 T& GLOrganismVector<T>::getGene(int index)
00153 {
00154 if (!checkIndex(index))
00155 {
00156 char errormsg[1000];
00157 sprintf(errormsg, "\nGLOrganismVector::getGene\n"
00158 "Index = %i"
00159 " is outside the organism's size [0, %i)\n",
00160 index, getSize());
00161 throw GLLogicError(errormsg);
00162 }
00163 return m_storage[index];
00164 }
00165
00171 template<class T>
00172 const T& GLOrganismVector<T>::getGene(int index) const
00173 {
00174 if (!checkIndex(index))
00175 {
00176 char errormsg[1000];
00177 sprintf(errormsg, "\nGLOrganismVector::getGene\n"
00178 "Index = %i"
00179 " is outside the organism's size [0, %i)\n",
00180 index, getSize());
00181 throw GLLogicError(errormsg);
00182 }
00183 return m_storage[index];
00184 }
00185
00190 template<class T>
00191 int GLOrganismVector<T>::getSize() const
00192 { return m_storage.size(); }
00193
00202 template<class T>
00203 bool GLOrganismVector<T>::isEqual(const GLBaseOrganism *organism,
00204 bool soft) const
00205 {
00209 const GLOrganismVector<T>* org =
00210 dynamic_cast<const GLOrganismVector<T>*>(organism);
00211
00212 if (org == NULL) return false;
00213 bool flag = (m_storage == org->m_storage);
00214 return flag &&
00215 (soft ||
00216 ((isEvaluated() == org->isEvaluated()) &&
00217 getFitness()->isEqual(org->getFitness()))
00218 );
00219 }
00220
00229 template<class T>
00230 bool GLOrganismVector<T>::isLess(const GLBaseOrganism *organism,
00231 bool soft) const
00232 {
00233 const GLOrganismVector<T>* org =
00234 nlutils::transform_pointer<const GLOrganismVector<T>,
00235 const GLBaseOrganism>
00236 (organism, "GLOrganismVector<T>::isLess\n"
00237 "Passed argument either not compatible or NULL");
00238
00239 int size = min(m_storage.size(), org->m_storage.size());
00240
00241 for (int i = 0; i < size; i++)
00242 {
00243 if (m_storage[i] != org->m_storage[i])
00244 return m_storage[i] < org->m_storage[i];
00245 }
00246
00247
00248 return m_storage.size() < org->m_storage.size();
00249 }
00250
00261 template<class T>
00262 GLBaseOrganism* GLOrganismVector<T>::makeClone(bool soft) const
00263 {
00264 if (!soft) return new GLOrganismVector<T>(*this);
00265 GLOrganismVector<T> *organism = new GLOrganismVector<T>(this->getSize());
00266 organism->copyGeneticData(this);
00267 return organism;
00268 }
00269
00275 template<class T>
00276 void GLOrganismVector<T>::moveGene(int old_position, int new_position)
00277 {
00278 if (!checkIndex(old_position) || !(checkIndex(new_position)))
00279 {
00280 char errormsg[1000];
00281 sprintf(errormsg, "\nGLOrganismVector::moveGene\n"
00282 "One of the indices -- new_position (%i) or "
00283 "old_position (%i)"
00284 " is outside the organism's size [0, %i)\n",
00285 old_position, new_position, getSize());
00286 throw GLLogicError(errormsg);
00287 }
00288
00289 if (old_position == new_position) return;
00290
00291 if (old_position < new_position)
00292 {
00293 rotate(m_storage.begin() + old_position,
00294 m_storage.begin() + old_position + 1,
00295 m_storage.begin() + new_position + 1);
00296 }
00297 else
00298 {
00299 rotate(m_storage.rbegin() + getSize() - old_position - 1,
00300 m_storage.rbegin() + getSize() - old_position,
00301 m_storage.rbegin() + getSize() - new_position);
00302 }
00303
00304 }
00305
00312 template<class T>
00313 void GLOrganismVector<T>::setChromosome(const vector<T>& chromosome)
00314 {
00315
00316
00317 if ((m_property_size == GLConstants::FIXED) &&
00318 (chromosome.size() != m_max_size))
00319 {
00320 char errormsg[1000];
00321 sprintf(errormsg, "\nGLOrganismVector<T>::setChromosome\n"
00322 "Size of the chromosome (%i) differs from the "
00323 "size of this fixed-size organism (%i)\n",
00324 (int)chromosome.size(),
00325 (int)m_max_size);
00326 throw GLLogicError(errormsg);
00327 }
00328 if ((m_property_size == GLConstants::NOT_FIXED) &&
00329 (chromosome.size() > m_max_size))
00330 {
00331 char errormsg[1000];
00332 sprintf(errormsg, "\nGLOrganismVector<T>::setChromosome\n"
00333 "Size of the chromosome (%i) exceeds the maximum "
00334 "on the size of the organism (%i)\n",
00335 (int)chromosome.size(),
00336 (int)m_max_size);
00337 throw GLLogicError(errormsg);
00338 }
00339
00340
00341 if (m_property_bounds == GLConstants::BOUNDED_GENES)
00342 {
00343 for(unsigned i = 0; i < chromosome.size(); i++)
00344 {
00345 if (!checkBounds(chromosome[i]))
00346 {
00347 char errormsg[1000];
00348 sprintf(errormsg, "\nGLOrganismVector<T>::setChromosome\n"
00349 "Element %i of the chromosome is outside "
00350 "the gene's bounds\n",
00351 i);
00352 throw GLLogicError(errormsg);
00353 }
00354 }
00355 }
00356
00357 m_storage = chromosome;
00358 }
00359
00365 template<class T>
00366 void GLOrganismVector<T>::setGene(int index, const T& gene)
00367 {
00368
00369 if (!checkIndex(index))
00370 {
00371 char errormsg[1000];
00372 sprintf(errormsg, "\nGLOrganismVector::setGene\n"
00373 "Index = %i"
00374 " is outside the organism's size [0, %i)\n",
00375 index, getSize());
00376 throw GLLogicError(errormsg);
00377 }
00378
00379 if (gene == getGene(index)) return;
00380
00381 if (!checkBounds(gene))
00382 {
00383 char errormsg[1000];
00384 sprintf(errormsg, "\nGLOrganismVector::setGene\n"
00385 "Passed gene is outside allowed bounds\n");
00386 throw GLLogicError(errormsg);
00387 }
00388 m_storage[index] = gene;
00389 resetFitness();
00390 }
00391
00402 template<class T>
00403 bool GLOrganismVector<T>:: setGeneBounds(const T& gene_min,
00404 const T& gene_max,
00405 bool correct_organism)
00406 {
00407 if (gene_min > gene_max)
00408 {
00409 char errormsg[1000];
00410 sprintf(errormsg, "\nGLOrganismVector<T>:: setGeneBounds\n"
00411 "\nInconsistency in bounds: "
00412 "gene_min > gene_max\n");
00413 throw GLLogicError(errormsg);
00414 }
00415 m_gene_min = gene_min;
00416 m_gene_max = gene_max;
00417 m_property_bounds = GLConstants::BOUNDED_GENES;
00418 if (!correct_organism) return false;
00419 bool was_corrected = false;
00420
00421
00422 for(int i = 0; i < getSize(); i++)
00423 {
00424 if (m_storage[i] < gene_min)
00425 {
00426 m_storage[i] = m_gene_min;
00427 was_corrected = true;
00428 continue;
00429 }
00430 if (m_storage[i] > gene_max)
00431 {
00432 m_storage[i] = m_gene_max;
00433 was_corrected = true;
00434 }
00435 }
00436 return was_corrected;
00437 }
00438
00444 template<class T>
00445 void GLOrganismVector<T>::setSizeData(unsigned init_size,
00446 unsigned max_size)
00447 {
00448
00449 if (init_size < 0)
00450 {
00451 char errormsg[1000];
00452 sprintf(errormsg, "GLOrganismVector<T>::setSizeData\n"
00453 "The organism size (%i) should be >= 0\n",
00454 init_size);
00455 }
00456
00457
00458 switch (m_property_size)
00459 {
00460 case GLConstants::FIXED:
00461 m_max_size = init_size;
00462 break;
00463 case GLConstants::NOT_FIXED:
00464 if (max_size < init_size)
00465 {
00466 char errormsg[1000];
00467 sprintf(errormsg, "\nGLOrganismVector<T>::setSizeData\n"
00468 "Maximum organism size (%i) set to be less than"
00469 "initial size (%i)\n",
00470 max_size, init_size);
00471 throw GLLogicError(errormsg);
00472 }
00473 m_max_size = max_size;
00474 break;
00475 }
00476 }
00477
00484 template<class T>
00485 void GLOrganismVector<T>::shuffleGenes(const vector<int>& gene_numbers)
00486 {
00487
00488 vector<T> genes;
00489 genes.reserve(gene_numbers.size());
00490 for(size_t i = 0; i < gene_numbers.size(); i++)
00491 genes.push_back(getGene(gene_numbers[i]));
00492
00493
00494 gl_shuffle_vector(genes);
00495
00496
00497 for(size_t i = 0; i < gene_numbers.size(); i++)
00498 setGene(gene_numbers[i], genes[i]);
00499 }
00500
00517 template<class T>
00518 void GLOrganismVector<T>::swapSections(GLBaseOrganism* anotherOrganism,
00519 int leftPos, int rightPos)
00520 {
00521
00522 GLOrganismVector<T>* org = nlutils::transform_pointer
00523 <GLOrganismVector<T>, GLBaseOrganism>(anotherOrganism,
00524 "anotherOrganism from GLOrganismVector<T>::swapTails");
00525
00526
00527 if (leftPos >= rightPos)
00528 {
00529 char errormsg[1000];
00530 sprintf(errormsg, "\nGLOrganismVector<T>::swapSections\n"
00531 "parameter leftPos (= %i) must < rightPos (= %i)",
00532 leftPos, rightPos);
00533 throw GLLogicError(errormsg);
00534 }
00535
00536
00537
00538 int maxPos = min(getSize(), org->getSize());
00539 if ((leftPos < 0) || (rightPos > maxPos))
00540 {
00541 char errormsg[1000];
00542 sprintf(errormsg, "\nGLOrganismVector<T>::swapSections\n"
00543 "One of the positions leftPos = %i or rightPos = %i "
00544 "is outside limits for the "
00545 "organisms [0, %i)",
00546 leftPos, rightPos, maxPos);
00547 throw GLLogicError(errormsg);
00548 }
00549
00550 swap_ranges(m_storage.begin() + leftPos, m_storage.begin() + rightPos,
00551 org->m_storage.begin() + leftPos);
00552 }
00553
00562 template<class T>
00563 void GLOrganismVector<T>::swapTails(GLBaseOrganism* anotherOrganism, int pos)
00564 {
00565
00566 GLOrganismVector<T>* org = nlutils::transform_pointer
00567 <GLOrganismVector<T>, GLBaseOrganism>(anotherOrganism,
00568 "anotherOrganism from GLOrganismVector<T>::swapTails");
00569
00570
00571 int maxPos = min(getSize(), org->getSize());
00572 if ((pos < 0) || (pos >= maxPos))
00573 {
00574 char errormsg[1000];
00575 sprintf(errormsg, "\nGLOrganismVector<T>::swapTails\n"
00576 "Position pos = %i is outside limits for this "
00577 "organisms [0, %i)",
00578 pos, maxPos);
00579 }
00580
00581 swap_ranges(m_storage.begin() + pos, m_storage.end(),
00582 org->m_storage.begin() + pos);
00583 }
00584
00589 template<class T>
00590 ostream& GLOrganismVector<T>::toStream(ostream& out) const
00591 {
00592 for(int i = 0; i < getSize(); i++)
00593 {
00594 out << getGene(i) << " ";
00595 }
00596 return out;
00597 }
00598
00604 template<class T>
00605 ostream& GLOrganismVector<T>::toStreamDebug(ostream& out) const
00606 {
00607 out << "Gene bounds property: "
00608 << GLConstants::toString(m_property_bounds) << endl
00609 << "Chromosome size property: "
00610 << GLConstants::toString(m_property_size) << endl
00611 << "Chromosome size: "
00612 << m_storage.size() << endl;
00613
00614 if (isEvaluated())
00615 {
00616 out << "Evaluated " << (*getFitness()) << endl;
00617 }
00618 else
00619 {
00620 out << "Not evaluated\n";
00621 }
00622
00623 for(int i = 0; i < getSize(); i++)
00624 {
00625 out << getGene(i) << " ";
00626 if ((i + 1) % 20 == 0)
00627 {
00628 out << endl;
00629 }
00630 }
00631 if ((getSize() + 1) % 20 != 0)
00632 {
00633 out << endl;
00634 }
00635 return out;
00636 }