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 00041 template <class EOT> 00042 class eoOpContainer : public eoGenOp<EOT> 00043 { 00044 public : 00046 eoOpContainer() : max_to_produce(0) {} 00047 00050 virtual ~eoOpContainer(void) {} 00051 00053 virtual unsigned max_production(void) 00054 { 00055 return max_to_produce; 00056 } 00057 00063 void add(eoOp<EOT>& _op, double _rate) 00064 { 00065 ops.push_back(&wrap_op<EOT>(_op, store)); 00066 rates.push_back(_rate); 00067 max_to_produce = std::max(max_to_produce,ops.back()->max_production()); 00068 } 00069 00070 virtual std::string className() const = 0; 00071 00072 protected : 00073 00074 std::vector<double> rates; 00075 std::vector<eoGenOp<EOT>*> ops; 00076 00077 private : 00078 eoFunctorStore store; 00079 unsigned max_to_produce; 00080 }; 00081 00087 template <class EOT> 00088 class eoSequentialOp : public eoOpContainer<EOT> 00089 { 00090 public: 00091 00092 using eoOpContainer<EOT>::ops; 00093 using eoOpContainer<EOT>::rates; 00094 00095 typedef unsigned position_type; 00096 00097 00098 void apply(eoPopulator<EOT>& _pop) { 00099 position_type pos = _pop.tellp(); 00100 for (size_t i = 0; i < rates.size(); ++i) { 00101 _pop.seekp(pos); 00102 do { 00103 if (eo::rng.flip(rates[i])) { 00104 // try 00105 // { 00106 // apply it to all the guys in the todo std::list 00107 (*ops[i])(_pop); 00108 // } 00109 // check for out of individuals and do nothing with that... 00110 // catch(eoPopulator<EOT>::OutOfIndividuals&) 00111 // { 00112 // std::cout << "Warning: not enough individuals to handle\n"; 00113 // return ; 00114 // } 00115 } 00116 00117 if (!_pop.exhausted()) 00118 ++_pop; 00119 } 00120 while (!_pop.exhausted()); 00121 } 00122 } 00123 virtual std::string className() const {return "SequentialOp";} 00124 00125 private: 00126 00127 std::vector<size_t> to_apply; 00128 std::vector<size_t> production; 00129 }; 00130 00131 00132 00134 template <class EOT> 00135 class eoProportionalOp : public eoOpContainer<EOT> 00136 { 00137 public: 00138 00139 using eoOpContainer< EOT >::ops; 00140 using eoOpContainer< EOT >::rates; 00141 00142 void apply(eoPopulator<EOT>& _pop) 00143 { 00144 unsigned i = eo::rng.roulette_wheel(rates); 00145 00146 try 00147 { 00148 (*ops[i])(_pop); 00149 ++_pop; 00150 } 00151 catch( typename eoPopulator<EOT>::OutOfIndividuals&) 00152 {} 00153 } 00154 virtual std::string className() const {return "ProportionalOp";} 00155 }; 00156 00157 00158 #endif 00159
1.4.7