00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- 00002 00003 //----------------------------------------------------------------------------- 00004 // eoOneToOneBreeder.h 00005 // (c) Maarten Keijzer and Marc Schoenauer, 2001 00006 /* 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library; if not, write to the Free Software 00019 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 00021 Contact: mkeijzer@dhi.dk 00022 Marc.Schoenauer@polytechnique.fr 00023 */ 00024 //----------------------------------------------------------------------------- 00025 00026 #ifndef eoOneToOneBreeder_h 00027 #define eoOneToOneBreeder_h 00028 00029 //----------------------------------------------------------------------------- 00030 00031 #include <eoOp.h> 00032 #include <eoGenOp.h> 00033 #include <eoPopulator.h> 00034 #include <eoSelectOne.h> 00035 #include <eoSequentialSelect.h> 00036 #include <eoBreed.h> 00037 #include <eoEvalFunc.h> 00038 #include <eoPopulator.h> 00039 #include <utils/eoHowMany.h> 00040 00041 /***************************************************************************** 00042 * eoOneToOneBreeder: transforms a population using 00043 * - an operator that MODIFIES only one parent from the populator 00044 * (though it can use any number aside) and thus generates ONE offspring) 00045 * - a local replacement between the parent and its offspring 00046 * 00047 * Typically, Differential Evolution (Storn and Price 94) and Deb et al's 00048 * G3 can be built on this 00049 **************************************************************************** 00050 */ 00051 template<class EOT> 00052 class eoOneToOneBreeder: public eoBreed<EOT> 00053 { 00054 public: 00062 eoOneToOneBreeder( 00063 eoGenOp<EOT>& _op, 00064 eoEvalFunc<EOT> & _eval, 00065 double _pReplace = 1.0, 00066 eoHowMany _howMany = eoHowMany(1.0) ) : 00067 op(_op), eval(_eval), select( false ), 00068 pReplace(_pReplace), howMany(_howMany) {} 00069 00070 00078 void operator()(const eoPop<EOT>& _parents, eoPop<EOT>& _offspring) 00079 { 00080 unsigned target = howMany(_parents.size()); 00081 00082 _offspring.clear(); 00083 eoSelectivePopulator<EOT> popit(_parents, _offspring, select); 00084 00085 for (unsigned iParent=0; iParent<target; iParent++) 00086 { 00087 unsigned pos = popit.tellp(); // remember current position 00088 EOT theParent = *popit; // remember the parent itself 00089 00090 // now apply operator - will modify the parent 00091 op(popit); 00092 00093 // replacement 00094 EOT & leOffspring = *popit; 00095 00096 // check: only one offspring? 00097 unsigned posEnd = popit.tellp(); 00098 if (posEnd != pos) 00099 throw std::runtime_error("Operator can only generate a SINGLE offspring in eoOneToOneBreeder"); 00100 00101 // do the tournament between parent and offspring 00102 eval(leOffspring); // first need to evaluate the offspring 00103 if (theParent > leOffspring) // old parent better than offspring 00104 if (rng.uniform() < pReplace) // if probability 00105 leOffspring = theParent; // replace 00106 // finally, go to next guy to handle 00107 ++popit; 00108 } 00109 } 00110 00112 virtual std::string className() const { return "eoOneToOneBreeder"; } 00113 00114 private: 00115 eoGenOp<EOT>& op; 00116 eoEvalFunc<EOT> & eval; 00117 eoSequentialSelect<EOT> select; 00118 double pReplace; 00119 eoHowMany howMany; 00120 }; 00121 00122 #endif 00123
1.5.5