EvolvingObjects
eoDualFitness.h
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_
 All Classes Namespaces Files Functions Variables Typedefs Friends