EvolvingObjects
|
00001 /* 00002 00003 (c) 2010 Thales group 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; version 2 00008 of the License. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 Contact: http://eodev.sourceforge.net 00020 00021 Authors: 00022 Johann Dréo <johann.dreo@thalesgroup.com> 00023 00024 */ 00025 00026 #ifndef _eoDualFitness_h_ 00027 #define _eoDualFitness_h_ 00028 00029 #include <functional> 00030 #include <iostream> 00031 #include <utility> // for std::pair 00032 #include <string> 00033 00034 #include <utils/eoStat.h> 00035 #include <utils/eoLogger.h> 00036 00041 00042 00067 template <class BaseType, class Compare > 00068 class eoDualFitness 00069 { 00070 protected: 00072 BaseType _value; 00073 00075 bool _is_feasible; 00076 00077 public: 00078 00080 00083 eoDualFitness() : 00084 _value(), 00085 _is_feasible(false) 00086 {} 00087 00089 eoDualFitness(const eoDualFitness& other) : 00090 _value(other._value), 00091 _is_feasible(other._is_feasible) 00092 {} 00093 00095 eoDualFitness(const BaseType& v, const bool& is_feasible) : 00096 _value(v), 00097 _is_feasible(is_feasible) 00098 {} 00099 00101 eoDualFitness(const std::pair<BaseType,bool>& dual) : 00102 _value(dual.first), 00103 _is_feasible(dual.second) 00104 {} 00105 00106 // FIXME is it a good idea to include implicit conversion here? 00114 operator BaseType(void) const { return _value; } 00115 00116 00117 inline bool is_feasible() const 00118 { 00119 return _is_feasible; 00120 } 00121 00122 inline BaseType value() const 00123 { 00124 return _value; 00125 } 00126 00128 eoDualFitness& operator=(const std::pair<BaseType,bool>& v) 00129 { 00130 _value = v.first; 00131 _is_feasible = v.second; 00132 return *this; 00133 } 00134 00136 template <class F, class Cmp> 00137 eoDualFitness<F,Cmp> & operator=(const eoDualFitness<BaseType, Compare>& other ) 00138 { 00139 if (this != &other) { 00140 this->_value = other._value; 00141 this->_is_feasible = other._is_feasible; 00142 } 00143 return *this; 00144 } 00145 00147 00152 bool operator<(const eoDualFitness& other) const 00153 { 00154 // am I better (less, by default) than the other ? 00155 00156 // if I'm feasible and the other is not 00157 if( this->_is_feasible && !other._is_feasible ) { 00158 // no, the other has a better fitness 00159 return false; 00160 00161 } else if( !this->_is_feasible && other._is_feasible ) { 00162 // yes, a feasible fitness is always better than an unfeasible one 00163 return true; 00164 00165 } else { 00166 // the two fitness are of the same type 00167 // lets rely on the comparator 00168 return Compare()(_value, other._value); 00169 } 00170 } 00171 00173 bool operator>( const eoDualFitness& other ) const { return other < *this; } 00174 00176 bool operator<=( const eoDualFitness& other ) const { return !(other < *this); } 00177 00179 bool operator>=(const eoDualFitness& other ) const { return !(*this < other); } 00180 00182 bool operator==(const eoDualFitness& other) const { return ( _is_feasible == other._is_feasible ) && ( _value == other._value ); } 00183 00184 public: 00185 00187 template <class F, class Cmp> 00188 friend 00189 eoDualFitness<F,Cmp> & operator+=( eoDualFitness<F,Cmp> & from, const eoDualFitness<F,Cmp> & that ) 00190 { 00191 from._value += that._value; 00192 00193 // true only if the two are feasible, else false 00194 from._is_feasible = from._is_feasible && that._is_feasible; 00195 00196 return from; 00197 } 00198 00200 template <class F, class Cmp> 00201 friend 00202 eoDualFitness<F,Cmp> & operator-=( eoDualFitness<F,Cmp> & from, const eoDualFitness<F,Cmp> & that ) 00203 { 00204 from._value -= that._value; 00205 00206 // true only if the two are feasible, else false 00207 from._is_feasible = from._is_feasible && that._is_feasible; 00208 00209 return from; 00210 } 00211 00212 // Add this fitness's value to that other, and return a _new_ instance with the result. 00213 template <class F, class Cmp> 00214 eoDualFitness<F,Cmp> operator+(const eoDualFitness<F,Cmp> & that) 00215 { 00216 eoDualFitness<F,Cmp> from( *this ); 00217 return from += that; 00218 } 00219 00220 // Add this fitness's value to that other, and return a _new_ instance with the result. 00221 template <class F, class Cmp> 00222 eoDualFitness<F,Cmp> operator-(const eoDualFitness<F,Cmp> & that) 00223 { 00224 eoDualFitness<F,Cmp> from( *this ); 00225 return from -= that; 00226 } 00227 00229 template <class F, class Cmp> 00230 friend 00231 std::ostream& operator<<(std::ostream& os, const eoDualFitness<F, Cmp>& f) 00232 { 00233 os << f._value << " " << f._is_feasible; 00234 return os; 00235 } 00236 00238 template <class F, class Cmp> 00239 friend 00240 std::istream& operator>>(std::istream& is, eoDualFitness<F, Cmp>& f) 00241 { 00242 F value; 00243 is >> value; 00244 00245 bool feasible; 00246 is >> feasible; 00247 00248 f = std::make_pair<F,bool>( value, feasible ); 00249 return is; 00250 } 00251 }; 00252 00254 typedef eoDualFitness<double, std::less<double> > eoMaximizingDualFitness; 00255 00257 typedef eoDualFitness<double, std::greater<double> > eoMinimizingDualFitness; 00258 00260 00262 template< class EOT> 00263 bool eoIsFeasible ( const EOT & sol ) { return sol.fitness().is_feasible(); } 00264 00265 00270 //template<class EOT, class T> 00271 template<class EOT, class EOSTAT> 00272 class eoDualStatSwitch : public eoStat< EOT, std::string > 00273 { 00274 public: 00275 using eoStat<EOT,std::string>::value; 00276 00277 // eoDualStatSwitch( eoStat<EOT,T> & stat_feasible, eoStat<EOT,T> & stat_unfeasible, std::string sep=" " ) : 00278 eoDualStatSwitch( EOSTAT & stat_feasible, EOSTAT & stat_unfeasible, std::string sep=" " ) : 00279 eoStat<EOT,std::string>( 00280 "?"+sep+"?", 00281 stat_feasible.longName()+sep+stat_unfeasible.longName() 00282 ), 00283 _stat_feasible(stat_feasible), 00284 _stat_unfeasible(stat_unfeasible), 00285 _sep(sep) 00286 { } 00287 00288 virtual void operator()( const eoPop<EOT> & pop ) 00289 { 00290 eoPop<EOT> pop_feasible; 00291 pop_feasible.reserve(pop.size()); 00292 00293 eoPop<EOT> pop_unfeasible; 00294 pop_unfeasible.reserve(pop.size()); 00295 00296 for( typename eoPop<EOT>::const_iterator ieot=pop.begin(), iend=pop.end(); ieot!=iend; ++ieot ) { 00297 /* 00298 if( ieot->invalid() ) { 00299 eo::log << eo::errors << "ERROR: trying to access to an invalid fitness" << std::endl; 00300 } 00301 */ 00302 if( ieot->fitness().is_feasible() ) { 00303 pop_feasible.push_back( *ieot ); 00304 } else { 00305 pop_unfeasible.push_back( *ieot ); 00306 } 00307 } 00308 00309 _stat_feasible( pop_feasible ); 00310 _stat_unfeasible( pop_unfeasible ); 00311 00312 std::ostringstream out; 00313 out << _stat_feasible.value() << _sep << _stat_unfeasible.value(); 00314 00315 value() = out.str(); 00316 } 00317 00318 protected: 00319 // eoStat<EOT,T> & _stat_feasible; 00320 // eoStat<EOT,T> & _stat_unfeasible; 00321 EOSTAT & _stat_feasible; 00322 EOSTAT & _stat_unfeasible; 00323 00324 std::string _sep; 00325 }; 00326 00328 #endif // _eoDualFitness_h_