EvolvingObjects
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 #include <string>
00025 #include <vector>
00026 #include <exception>
00027 #include <boost/python.hpp>
00028 
00029 #include <EO.h>
00030 
00031 struct index_error : public std::exception
00032 {
00033     index_error(std::string w) : what(w) {};
00034     virtual ~index_error() throw() {}
00035     std::string what;
00036 };
00037 
00038 class PyFitness : public boost::python::object
00039 {
00040 public :
00041 
00042     typedef PyFitness fitness_traits; // it's its own traits class :-)
00043 
00044     PyFitness() : boost::python::object() {}
00045 
00046     template <class T>
00047     PyFitness(const T& o) : boost::python::object(o) {}
00048 
00049     static unsigned nObjectives() { return objective_info.size(); }
00050     static double tol() { return 1e-6; }
00051     static bool maximizing(int which) { return objective_info[which] > 0; }
00052 
00053     static void setObjectivesSize(int sz) { objective_info.resize(sz, 0); }
00054     static void setObjectivesValue(unsigned which, int value)
00055     {
00056         if (which >= objective_info.size())
00057             {
00058                 throw index_error("Too few elements allocated, resize objectives first");
00059             }
00060 
00061         objective_info[which] = value;
00062     }
00063 
00064     static std::vector<int> objective_info;
00065 
00066     bool dominates(const PyFitness& oth) const;
00067 
00068     double operator[](int i) const
00069     {
00070         boost::python::extract<double> x(object::operator[](i));
00071 
00072         if (!x.check())
00073             throw std::runtime_error("PyFitness: does not contain doubles");
00074         return x();
00075     }
00076 
00077     bool operator<(const PyFitness& other) const
00078     {
00079         if (objective_info.size() == 0)
00080             {
00081                 const object& self = *this;
00082                 const object& oth = other;
00083                 return self < oth;
00084             }
00085         // otherwise use objective_info
00086 
00087         for (unsigned i = 0; i < objective_info.size(); ++i)
00088             {
00089                 double a = objective_info[i] * operator[](i);
00090                 double b = objective_info[i] * other[i];
00091 
00092                 if ( fabs(a - b) > tol())
00093                     {
00094                         if (a < b)
00095                             return true;
00096                         return false;
00097                     }
00098             }
00099 
00100         return false;
00101     }
00102 
00103     bool operator>(const PyFitness& other) const
00104     {
00105         return other.operator<(*this);
00106     }
00107 
00108     void printOn(std::ostream& os) const { const boost::python::object& o = *this; boost::python::api::operator<<(os,o); }
00109     friend std::ostream& operator<<(std::ostream& os, const PyFitness& p) { p.printOn(os); return os;  }
00110     friend std::istream& operator>>(std::istream& is, PyFitness& p) { boost::python::object o; is >> o; p = o; return is; }
00111 };
00112 
00113 struct PyEO : public EO< PyFitness  >
00114 {
00115     typedef PyFitness Fitness;
00116 
00117     boost::python::object getFitness() const { return invalid()? Fitness(): fitness(); }
00118     void setFitness(boost::python::object f) { if (f == Fitness()) invalidate(); else fitness(f); }
00119 
00120     boost::python::object getGenome() const { return genome; }
00121     void setGenome(boost::python::object g) { genome = g; }
00122     boost::python::object genome;
00123 
00124     std::string to_string() const
00125     {
00126         std::string result;
00127         result += boost::python::extract<const char*>(boost::python::str(getFitness()));
00128         result += ' ';
00129         result += boost::python::extract<const char*>(boost::python::str(genome));
00130         return result;
00131     }
00132 
00133     bool operator<(const PyEO& other) const { return EO<Fitness>::operator<(other); }
00134     bool operator>(const PyEO& other) const { return EO<Fitness>::operator>(other); }
00135 
00136 };
00137 
00138 std::ostream& operator<<(std::ostream& os, const PyEO& _eo);
00139 
00140 struct PyEO_pickle_suite : boost::python::pickle_suite
00141 {
00142     typedef PyEO::Fitness Fitness;
00143 
00144     static boost::python::tuple getstate(const PyEO& _eo)
00145     {
00146         return boost::python::make_tuple(_eo.getFitness(), _eo.genome);
00147     }
00148 
00149     static 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
 All Classes Namespaces Files Functions Variables Typedefs Friends