PyEO.h

00001 /*
00002     PyEO
00003     
00004     Copyright (C) 2003 Maarten Keijzer
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 */
00020 
00021 #ifndef PYEO_H
00022 #define PYEO_H
00023 
00024 
00025 #include <string>
00026 #include <vector>
00027 #include <exception>
00028 #include <boost/python.hpp>
00029 
00030 #include <EO.h>
00031 struct index_error : public std::exception { 
00032     index_error(std::string w) : what(w) {}; 
00033     virtual ~index_error() throw() {}
00034     std::string what; 
00035 };
00036 
00037 class PyFitness : public boost::python::object
00038 {
00039     public :
00040     
00041     typedef PyFitness fitness_traits; // it's its own traits class :-)
00042         
00043     PyFitness() : boost::python::object() {}
00044     
00045     template <class T>
00046     PyFitness(const T& o) : boost::python::object(o) {}
00047     
00048     static unsigned nObjectives() { return objective_info.size(); }
00049     static double tol() { return 1e-6; }
00050     static bool maximizing(int which) { return objective_info[which] > 0; }
00051     
00052     static void setObjectivesSize(int sz) { objective_info.resize(sz, 0); }
00053     static void setObjectivesValue(unsigned which, int value)
00054     {
00055         if (which >= objective_info.size())
00056         {
00057             throw index_error("Too few elements allocated, resize objectives first");
00058         }
00059 
00060         objective_info[which] = value;
00061     }
00062     
00063     static std::vector<int> objective_info;
00064     
00065     bool dominates(const PyFitness& oth) const;
00066     
00067     double operator[](int i) const 
00068     { 
00069         boost::python::extract<double> x(object::operator[](i)); 
00070     
00071         if (!x.check())
00072             throw std::runtime_error("PyFitness: does not contain doubles");
00073         return x();
00074     }
00075  
00076     bool operator<(const PyFitness& other) const 
00077     { 
00078         if (objective_info.size() == 0)
00079         {
00080             const object& self = *this;
00081             const object& oth = other;
00082             return self < oth;
00083         }
00084         // otherwise use objective_info
00085     
00086         for (unsigned i = 0; i < objective_info.size(); ++i)
00087         {
00088             double a = objective_info[i] * operator[](i);
00089             double b = objective_info[i] * other[i];
00090 
00091             if ( fabs(a - b) > tol())
00092             {
00093                 if (a < b)
00094                     return true;
00095                 return false;
00096             }
00097         }
00098 
00099         return false;
00100     }
00101     
00102     bool operator>(const PyFitness& other) const 
00103     { 
00104         return other.operator<(*this);
00105     }
00106     
00107     void printOn(std::ostream& os) const { const boost::python::object& o = *this; boost::python::api::operator<<(os,o); }
00108     friend std::ostream& operator<<(std::ostream& os, const PyFitness& p) { p.printOn(os); return os;  }
00109     friend std::istream& operator>>(std::istream& is, PyFitness& p) { boost::python::object o; is >> o; p = o; return is; }
00110 };
00111 
00112 struct PyEO : public EO< PyFitness  >
00113 {  
00114     typedef PyFitness Fitness;
00115     
00116     boost::python::object getFitness() const { return invalid()? Fitness(): fitness(); }
00117     void setFitness(boost::python::object f) { if (f == Fitness()) invalidate(); else fitness(f); }
00118 
00119     boost::python::object getGenome() const { return genome; }
00120     void setGenome(boost::python::object g) { genome = g; }
00121     boost::python::object genome;
00122     
00123     std::string to_string() const
00124     {
00125         std::string result;
00126         result += boost::python::extract<const char*>(boost::python::str(getFitness()));
00127         result += ' ';
00128         result += boost::python::extract<const char*>(boost::python::str(genome));
00129         return result;
00130     }
00131 
00132     bool operator<(const PyEO& other) const { return EO<Fitness>::operator<(other); }
00133     bool operator>(const PyEO& other) const { return EO<Fitness>::operator>(other); }
00134 
00135 };
00136 
00137 std::ostream& operator<<(std::ostream& os, const PyEO& _eo);
00138 
00139 struct PyEO_pickle_suite : boost::python::pickle_suite
00140 {
00141     typedef PyEO::Fitness Fitness;
00142     
00143     static
00144     boost::python::tuple getstate(const PyEO& _eo)
00145     {
00146         return boost::python::make_tuple(_eo.getFitness(), _eo.genome);
00147     }
00148     static
00149     void setstate(PyEO& _eo, boost::python::tuple pickled)
00150     {
00151         _eo.setFitness( Fitness(pickled[0]) );
00152         _eo.genome = pickled[1];
00153     }
00154 };
00155 
00156 #endif

Generated on Thu Oct 19 05:06:42 2006 for EO by  doxygen 1.3.9.1