EvolvingObjects
|
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- 00002 00003 //----------------------------------------------------------------------------- 00004 // eoOpContainer.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 _eoOpContainer_H 00027 #define _eoOpContainer_H 00028 00029 #include <eoGenOp.h> 00030 00043 template <class EOT> 00044 class eoOpContainer : public eoGenOp<EOT> 00045 { 00046 public : 00048 eoOpContainer() : max_to_produce(0) {} 00049 00052 virtual ~eoOpContainer(void) {} 00053 00055 virtual unsigned max_production(void) 00056 { 00057 return max_to_produce; 00058 } 00059 00065 void add(eoOp<EOT>& _op, double _rate) 00066 { 00067 ops.push_back(&wrap_op<EOT>(_op, store)); 00068 rates.push_back(_rate); 00069 max_to_produce = std::max(max_to_produce,ops.back()->max_production()); 00070 } 00071 00072 virtual std::string className() const = 0; 00073 00074 protected : 00075 00076 std::vector<double> rates; 00077 std::vector<eoGenOp<EOT>*> ops; 00078 00079 private : 00080 eoFunctorStore store; 00081 unsigned max_to_produce; 00082 }; 00083 00091 template <class EOT> 00092 class eoSequentialOp : public eoOpContainer<EOT> 00093 { 00094 public: 00095 00096 using eoOpContainer<EOT>::ops; 00097 using eoOpContainer<EOT>::rates; 00098 00099 typedef unsigned position_type; 00100 00101 00102 void apply(eoPopulator<EOT>& _pop) { 00103 _pop.reserve( this->max_production() ); 00104 00105 position_type pos = _pop.tellp(); 00106 for (size_t i = 0; i < rates.size(); ++i) { 00107 _pop.seekp(pos); 00108 do { 00109 if (eo::rng.flip(rates[i])) { 00110 // try 00111 // { 00112 // apply it to all the guys in the todo std::list 00113 00114 //(*ops[i])(_pop); 00115 00116 ops[i]->apply(_pop); 00117 00118 // } 00119 // check for out of individuals and do nothing with that... 00120 // catch(eoPopulator<EOT>::OutOfIndividuals&) 00121 // { 00122 // std::cout << "Warning: not enough individuals to handle\n"; 00123 // return ; 00124 // } 00125 } 00126 00127 if (!_pop.exhausted()) 00128 ++_pop; 00129 } 00130 while (!_pop.exhausted()); 00131 } 00132 } 00133 virtual std::string className() const {return "SequentialOp";} 00134 00135 private: 00136 00137 std::vector<size_t> to_apply; 00138 std::vector<size_t> production; 00139 }; 00140 00141 00142 00144 template <class EOT> 00145 class eoProportionalOp : public eoOpContainer<EOT> 00146 { 00147 public: 00148 00149 using eoOpContainer< EOT >::ops; 00150 using eoOpContainer< EOT >::rates; 00151 00152 void apply(eoPopulator<EOT>& _pop) 00153 { 00154 unsigned i = eo::rng.roulette_wheel(rates); 00155 00156 try 00157 { 00158 (*ops[i])(_pop); 00159 ++_pop; 00160 } 00161 catch( typename eoPopulator<EOT>::OutOfIndividuals&) 00162 {} 00163 } 00164 virtual std::string className() const {return "ProportionalOp";} 00165 }; 00166 00167 00168 #endif