EvolvingObjects
|
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- 00002 00003 //----------------------------------------------------------------------------- 00004 // eoMerge.h 00005 // Base class for elitist-merging classes 00006 // (c) GeNeura Team, 1998 00007 /* 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Lesser General Public 00010 License as published by the Free Software Foundation; either 00011 version 2 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Lesser General Public License for more details. 00017 00018 You should have received a copy of the GNU Lesser General Public 00019 License along with this library; if not, write to the Free Software 00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00021 00022 Contact: todos@geneura.ugr.es, http://geneura.ugr.es 00023 */ 00024 //----------------------------------------------------------------------------- 00025 00026 #ifndef eoMerge_h 00027 #define eoMerge_h 00028 00029 //----------------------------------------------------------------------------- 00030 00031 #include <stdexcept> 00032 00033 // EO includes 00034 #include <eoPop.h> // eoPop 00035 #include <eoFunctor.h> // eoMerge 00036 #include <utils/eoLogger.h> 00037 00052 template<class Chrom> class eoMerge: public eoBF<const eoPop<Chrom>&, eoPop<Chrom>&, void> 00053 {}; 00054 00061 template <class EOT> class eoElitism : public eoMerge<EOT> 00062 { 00063 public : 00064 eoElitism(double _rate, bool _interpret_as_rate = true): 00065 rate(0), combien(0) 00066 { 00067 if (_interpret_as_rate) 00068 { 00069 if ( (_rate<0) || (_rate>1) ) 00070 throw std::logic_error("eoElitism: rate shoud be in [0,1]"); 00071 rate = _rate; 00072 } 00073 else 00074 { 00075 if (_rate<0) 00076 throw std::logic_error("Negative number of offspring in eoElitism!"); 00077 combien = (unsigned int)_rate; 00078 if (combien != _rate) 00079 eo::log << eo::warnings << "Warning: Number of guys to merge in eoElitism was rounded" << std::endl; 00080 } 00081 } 00082 00083 void operator()(const eoPop<EOT>& _pop, eoPop<EOT>& _offspring) 00084 { 00085 if ((combien == 0) && (rate == 0.0)) 00086 return; 00087 unsigned combienLocal; 00088 if (combien == 0) // rate is specified 00089 combienLocal = (unsigned int) (rate * _pop.size()); 00090 else 00091 combienLocal = combien; 00092 00093 if (combienLocal > _pop.size()) 00094 throw std::logic_error("Elite larger than population"); 00095 00096 std::vector<const EOT*> result; 00097 _pop.nth_element(combienLocal, result); 00098 00099 for (size_t i = 0; i < result.size(); ++i) 00100 { 00101 _offspring.push_back(*result[i]); 00102 } 00103 } 00104 00105 private : 00106 double rate; 00107 unsigned combien; 00108 }; 00109 00114 template <class EOT> class eoNoElitism : public eoElitism<EOT> 00115 { 00116 public : 00117 eoNoElitism() : eoElitism<EOT>(0) {} 00118 }; 00119 00124 template <class EOT> class eoPlus : public eoMerge<EOT> 00125 { 00126 public : 00127 void operator()(const eoPop<EOT>& _pop, eoPop<EOT>& _offspring) 00128 { 00129 _offspring.reserve(_offspring.size() + _pop.size()); 00130 00131 for (size_t i = 0; i < _pop.size(); ++i) 00132 { 00133 _offspring.push_back(_pop[i]); 00134 } 00135 } 00136 00137 private : 00138 }; 00139 00140 //----------------------------------------------------------------------------- 00141 00142 #endif