eoMerge.h

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 
00048 template<class Chrom> class eoMerge: public eoBF<const eoPop<Chrom>&, eoPop<Chrom>&, void>
00049 {};
00050 
00055 template <class EOT> class eoElitism : public eoMerge<EOT>
00056 {
00057 public :
00058   eoElitism(double  _rate, bool _interpret_as_rate = true):
00059     rate(0), combien(0)
00060   {
00061     if (_interpret_as_rate)
00062       {
00063         if ( (_rate<0) || (_rate>1) )
00064           throw std::logic_error("eoElitism: rate shoud be in [0,1]");
00065         rate = _rate;
00066       }
00067     else
00068       {
00069         if (_rate<0)
00070           throw std::logic_error("Negative number of offspring in eoElitism!");
00071         combien = (unsigned int)_rate;
00072         if (combien != _rate)
00073           std::cout << "Warning: Number of guys to merge in eoElitism was rounded";
00074       }
00075   }
00076   
00077   void operator()(const eoPop<EOT>& _pop, eoPop<EOT>& _offspring)
00078   {
00079     if ((combien == 0) && (rate == 0.0))
00080       return;
00081     unsigned combienLocal;
00082     if (combien == 0)      // rate is specified
00083       combienLocal = (unsigned int) (rate * _pop.size());
00084     else
00085       combienLocal = combien;
00086     
00087     if (combienLocal > _pop.size())
00088       throw std::logic_error("Elite larger than population");
00089     
00090     std::vector<const EOT*> result;
00091     _pop.nth_element(combienLocal, result);
00092     
00093     for (size_t i = 0; i < result.size(); ++i)
00094       {
00095         _offspring.push_back(*result[i]);
00096       }
00097   }
00098   
00099 private :
00100   double rate;
00101   unsigned combien;
00102 };
00103 
00107 template <class EOT> class eoNoElitism : public eoElitism<EOT>
00108 {
00109     public :
00110         eoNoElitism() : eoElitism<EOT>(0) {}
00111 };
00112 
00116 template <class EOT> class eoPlus : public eoMerge<EOT>
00117 {
00118     public :
00119         void operator()(const eoPop<EOT>& _pop, eoPop<EOT>& _offspring)
00120         {
00121             _offspring.reserve(_offspring.size() + _pop.size());
00122 
00123             for (size_t i = 0; i < _pop.size(); ++i)
00124             {
00125                 _offspring.push_back(_pop[i]);
00126             }
00127         }
00128 
00129     private :
00130 };
00131 
00132 //-----------------------------------------------------------------------------
00133 
00134 #endif 

Generated on Thu Oct 19 05:06:36 2006 for EO by  doxygen 1.3.9.1