00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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;
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
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