# eoParetoFitness.h

    00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
    00002
    00003 //-----------------------------------------------------------------------------
    00004 // eoParetoFitness.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: mak@dhi.dk
    00022              Marc.Schoenauer@inria.fr
    00023  */
    00024 //-----------------------------------------------------------------------------
    00025
    00026 #ifndef _eoParetoFitness_h
    00027 #define _eoParetoFitness_h
    00028
    00029 #include <math.h>
    00030 #include <vector>
    00031 #include <stdexcept>
    00032 #include <iostream>
    00033
    00034
    00042 class eoParetoFitnessTraits
    00043 {
    00044   public :
    00045
    00046   static unsigned nObjectives()          { return 2; }
    00047   static double tol()               { return 1e-6; }
    00048   static bool maximizing(int which) { return true; } // by default: all are maximizing
    00049 };
    00050
    00056 class eoVariableParetoTraits : public eoParetoFitnessTraits
    00057 {
    00058 public :
    00060   static void setUp(unsigned _n, std::vector<bool> & _b)
    00061   {
    00062     // possible problems
    00063     if ( nObj && (nObj != _n) )    // was already set to a different value
    00064       {
    00065         std::cout << "WARNING\n";
    00066         std::cout << "WARNING : you are changing the number of objectives\n";
    00067         std::cout << "WARNING : Make sure all existing objects are destroyed\n";
    00068         std::cout << "WARNING\n";
    00069       }
    00070     nObj=_n;
    00071     bObj=_b;
    00072     if (nObj != bObj.size())
    00073       throw std::runtime_error("Number of objectives and min/max size don't match in VariableParetoTraits::setup");
    00074   }
    00075
    00077   static unsigned nObjectives()
    00078   {
    00079 #ifndef NDEBUG
    00080     if (!nObj)
    00081       throw std::runtime_error("Number of objectives not assigned in VariableParetoTraits");
    00082 #endif
    00083     return nObj;
    00084   }
    00085   static bool maximizing(unsigned _i)
    00086   {
    00087 #ifndef NDEBUG
    00088     if (_i >= bObj.size())
    00089       throw std::runtime_error("Wrong index in VariableParetoTraits");
    00090 #endif
    00091     return bObj[_i];
    00092   }
    00093 private:
    00094   static unsigned nObj;
    00095   static std::vector<bool> bObj;
    00096 };
    00097
    00107 template <class FitnessTraits = eoParetoFitnessTraits>
    00108 class eoParetoFitness : public std::vector<double>
    00109 {
    00110 public :
    00111
    00112   typedef FitnessTraits fitness_traits;
    00113
    00114   eoParetoFitness(void) : std::vector<double>(FitnessTraits::nObjectives(),0.0) {}
    00115
    00116   // Ctr from a std::vector<double>
    00117   eoParetoFitness(std::vector<double> & _v) : std::vector<double>(_v) {}
    00118
    00119
    00123   static void setUp(unsigned _n, std::vector<bool> & _b) {FitnessTraits::setUp(_n, _b);}
    00124   static bool maximizing(unsigned _i) { return FitnessTraits::maximizing(_i);}
    00125
    00127   //bool operator<(const eoParetoFitness<FitnessTraits>& _other) const
    00128   bool dominates(const eoParetoFitness<FitnessTraits>& _other) const
    00129   {
    00130     bool dom = false;
    00131
    00132     double tol = FitnessTraits::tol();
    00133     const std::vector<double>& performance = *this;
    00134     const std::vector<double>& otherperformance = _other;
    00135
    00136     for (unsigned i = 0; i < FitnessTraits::nObjectives(); ++i)
    00137     {
    00138       bool maxim = FitnessTraits::maximizing(i);
    00139       double aval = maxim? performance[i] : -performance[i];
    00140       double bval = maxim? otherperformance[i] : -otherperformance[i];
    00141
    00142       if (fabs(aval - bval) > tol)
    00143       {
    00144         if (aval < bval)
    00145         {
    00146           return false; // cannot dominate
    00147         }
    00148         // else aval < bval
    00149         dom = true; // for the moment: goto next objective
    00150       }
    00151       //else they're equal in this objective, goto next
    00152     }
    00153
    00154     return dom;
    00155   }
    00156
    00158   bool operator<(const eoParetoFitness<FitnessTraits>& _other) const
    00159   {
    00160     double tol = FitnessTraits::tol();
    00161     const std::vector<double>& performance = *this;
    00162     const std::vector<double>& otherperformance = _other;
    00163     for (unsigned i = 0; i < FitnessTraits::nObjectives(); ++i)
    00164     {
    00165       bool maxim = FitnessTraits::maximizing(i);
    00166       double aval = maxim? performance[i] : -performance[i];
    00167       double bval = maxim? otherperformance[i] : -otherperformance[i];
    00168
    00169       if (fabs(aval-bval) > tol)
    00170       {
    00171         if (aval < bval)
    00172           return true;
    00173
    00174         return false;
    00175       }
    00176     }
    00177
    00178     return false;
    00179   }
    00180
    00181   bool operator>(const eoParetoFitness<FitnessTraits>& _other) const
    00182   {
    00183     return _other < *this;
    00184   }
    00185
    00186   bool operator<=(const eoParetoFitness<FitnessTraits>& _other) const
    00187   {
    00188     return operator==(_other) || operator<(_other);
    00189   }
    00190
    00191   bool operator>=(const eoParetoFitness<FitnessTraits>& _other) const
    00192   {
    00193     return _other <= *this;
    00194   }
    00195
    00196   bool operator==(const eoParetoFitness<FitnessTraits>& _other) const
    00197   { // check if they're all within tolerance
    00198     for (unsigned i = 0; i < size(); ++i)
    00199     {
    00200       if (fabs(operator[](i) - _other[i]) > FitnessTraits::tol())
    00201       {
    00202         return false;
    00203       }
    00204     }
    00205     return true;
    00206   }
    00207
    00208   bool operator!=(const eoParetoFitness<FitnessTraits>& _other) const
    00209   { return ! operator==(_other); }
    00210
    00211 };
    00212
    00213 template <class FitnessTraits>
    00214 std::ostream& operator<<(std::ostream& os, const eoParetoFitness<FitnessTraits>& fitness)
    00215 {
    00216   for (unsigned i = 0; i < fitness.size(); ++i)
    00217   {
    00218     os << fitness[i] << ' ';
    00219   }
    00220   return os;
    00221 }
    00222
    00223 template <class FitnessTraits>
    00224 std::istream& operator>>(std::istream& is, eoParetoFitness<FitnessTraits>& fitness)
    00225 {
    00226   fitness = eoParetoFitness<FitnessTraits>();
    00227   for (unsigned i = 0; i < fitness.size(); ++i)
    00228   {
    00229     is >> fitness[i];
    00230   }
    00231   return is;
    00232 }
    00233
    00234 #endif