# eoParetoConstraintFitness.h

    00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
    00002
    00003 //-----------------------------------------------------------------------------
    00004 // eoParetoConstraintFitness.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@cs.vu.nl
    00022              Marc.Schoenauer@inria.fr
    00023  */
    00024 //-----------------------------------------------------------------------------
    00025
    00026 #ifndef _eoParetoConstraintFitness_h
    00027 #define _eoParetoConstraintFitness_h
    00028
    00029 #include <math.h>
    00030 #include <vector>
    00031 #include <stdexcept>
    00032 #include <iostream>
    00033
    00034 #include <eoParetoFitness.h>
    00035
    00060 template <class FitnessTraits = eoParetoFitnessTraits>
    00061 class eoParetoOneConstraintFitness : public std::vector<double>
    00062 {
    00063 private:
    00064   // this class implements only 1 inequality constraint
    00065   //               (must ponder a bit for generality without huge overload)
    00066   double constraintValue;          // inequality cstr - must be negative
    00067
    00068 public :
    00069   typedef FitnessTraits fitness_traits;
    00070
    00071   eoParetoOneConstraintFitness(void) : std::vector<double>(FitnessTraits::nObjectives(),0.0)  {}
    00072
    00073   // Ctr from a std::vector<double> (size nObjectives+1)
    00074   eoParetoOneConstraintFitness(std::vector<double> & _v) :
    00075     std::vector<double>(_v)
    00076   {
    00077 #ifndef NDEBUG
    00078     if (_v.size() != fitness_traits::nObjectives()+1)
    00079       throw std::runtime_error("Size error in Ctor of eoParetoOneConstraintFitness from std::vector");
    00080 #endif
    00081     constraintValue = _v[fitness_traits::nObjectives()];
    00082     resize(fitness_traits::nObjectives());
    00083   }
    00084
    00085   // Ctr from a std::vector<double> and a value
    00086   eoParetoOneConstraintFitness(std::vector<double> & _v, double _c) :
    00087     std::vector<double>(_v), constraintValue(_c)
    00088   {
    00089 #ifndef NDEBUG
    00090     if (_v.size() != fitness_traits::nObjectives())
    00091       throw std::runtime_error("Size error in Ctor of eoParetoOneConstraintFitness from std::vector and value");
    00092 #endif
    00093   }
    00094
    00095
    00099   static void setUp(unsigned _n, std::vector<bool> & _b) {FitnessTraits::setUp(_n, _b);}
    00100   static bool maximizing(unsigned _i) { return FitnessTraits::maximizing(_i);}
    00101
    00102   bool feasible() const { return constraintValue<=0;}
    00103   double violation() const { return (feasible()?0.0:constraintValue);}
    00104   double ConstraintValue() const {return constraintValue;}
    00105   void ConstraintValue(double _c) {constraintValue=_c;}
    00106
    00108   //bool operator<(const eoParetoFitness<FitnessTraits>& _other) const
    00109   bool dominates(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
    00110   {
    00111     bool dom = false;
    00112
    00113     double tol = FitnessTraits::tol();
    00114     const std::vector<double>& performance = *this;
    00115     const std::vector<double>& otherperformance = _other;
    00116
    00117     if (feasible() && _other.feasible())
    00118     // here both are feasible: do the "standard" domination
    00119       for (unsigned i = 0; i < FitnessTraits::nObjectives(); ++i)
    00120         {
    00121           bool maxim = FitnessTraits::maximizing(i);
    00122           double aval = maxim? performance[i] : -performance[i];
    00123           double bval = maxim? otherperformance[i] : -otherperformance[i];
    00124
    00125           if (fabs(aval - bval) > tol)
    00126             {
    00127               if (aval < bval)
    00128                 {
    00129                   return false; // cannot dominate
    00130                 }
    00131               // else aval < bval
    00132               dom = true; // for the moment: goto next objective
    00133             }
    00134           //else they're equal in this objective, goto next
    00135         }
    00136     else
    00137       {                    // one at least is not feasible
    00138         if (feasible())
    00139           return true;             // feasible wins
    00140         else if (_other.feasible())
    00141           return false;            // feasible wins
    00142         return (violation()<_other.violation()); // smallest violation wins
    00143       }
    00144
    00145     return dom;
    00146   }
    00147
    00149   bool operator<(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
    00150   {
    00151     double tol = FitnessTraits::tol();
    00152     const std::vector<double>& performance = *this;
    00153     const std::vector<double>& otherperformance = _other;
    00154     for (unsigned i = 0; i < FitnessTraits::nObjectives(); ++i)
    00155     {
    00156       bool maxim = FitnessTraits::maximizing(i);
    00157       double aval = maxim? performance[i] : -performance[i];
    00158       double bval = maxim? otherperformance[i] : -otherperformance[i];
    00159
    00160       if (fabs(aval-bval) > tol)
    00161       {
    00162         if (aval < bval)
    00163           return true;
    00164
    00165         return false;
    00166       }
    00167     }
    00168
    00169     return false;
    00170   }
    00171
    00172   bool operator>(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
    00173   {
    00174     return _other < *this;
    00175   }
    00176
    00177   bool operator<=(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
    00178   {
    00179     return operator==(_other) || operator<(_other);
    00180   }
    00181
    00182   bool operator>=(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
    00183   {
    00184     return _other <= *this;
    00185   }
    00186
    00187   bool operator==(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
    00188   { // check if they're all within tolerance
    00189     for (unsigned i = 0; i < size(); ++i)
    00190     {
    00191       if (fabs(operator[](i) - _other[i]) > FitnessTraits::tol())
    00192       {
    00193         return false;
    00194       }
    00195     }
    00196     return true;
    00197   }
    00198
    00199   bool operator!=(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
    00200   { return ! operator==(_other); }
    00201
    00202 };
    00203
    00204 template <class FitnessTraits>
    00205 std::ostream& operator<<(std::ostream& os, const eoParetoOneConstraintFitness<FitnessTraits>& fitness)
    00206 {
    00207   for (unsigned i = 0; i < fitness.size(); ++i)
    00208   {
    00209     os << fitness[i] << ' ';
    00210   }
    00211   os << fitness.ConstraintValue() << " " ;
    00212   return os;
    00213 }
    00214
    00215 template <class FitnessTraits>
    00216 std::istream& operator>>(std::istream& is, eoParetoOneConstraintFitness<FitnessTraits>& fitness)
    00217 {
    00218   fitness = eoParetoOneConstraintFitness<FitnessTraits>();
    00219   for (unsigned i = 0; i < fitness.size(); ++i)
    00220   {
    00221     is >> fitness[i];
    00222   }
    00223   double r;
    00224   is >> r;
    00225   fitness.ConstraintValue(r);
    00226   return is;
    00227 }
    00228
    00229 #endif