# 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