added
This commit is contained in:
parent
0a4fb55031
commit
5bf5b1e5cb
2 changed files with 374 additions and 0 deletions
221
eo/src/pyeo/PyEO.cpp
Normal file
221
eo/src/pyeo/PyEO.cpp
Normal file
|
|
@ -0,0 +1,221 @@
|
||||||
|
/*
|
||||||
|
PyEO
|
||||||
|
|
||||||
|
Copyright (C) 2003 Maarten Keijzer
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <eoPop.h>
|
||||||
|
#include "PyEO.h"
|
||||||
|
|
||||||
|
|
||||||
|
// static member, needs to be instantiated somewhere
|
||||||
|
std::vector<int> PyFitness::objective_info;
|
||||||
|
|
||||||
|
bool PyFitness::dominates(const PyFitness& oth) const
|
||||||
|
{
|
||||||
|
bool dom = false;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < nObjectives(); ++i)
|
||||||
|
{
|
||||||
|
int objective = objective_info[i];
|
||||||
|
|
||||||
|
if (objective == 0) // ignore
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool maxim = objective > 0;
|
||||||
|
|
||||||
|
double aval = maxim? (*this)[i] : -(*this)[i];
|
||||||
|
double bval = maxim? oth[i] : -oth[i];
|
||||||
|
|
||||||
|
if (fabs(aval - bval) > tol())
|
||||||
|
{
|
||||||
|
if (aval < bval)
|
||||||
|
{
|
||||||
|
return false; // cannot dominate
|
||||||
|
}
|
||||||
|
// else aval < bval
|
||||||
|
dom = true; // for the moment: goto next objective
|
||||||
|
}
|
||||||
|
//else they're equal in this objective, goto next
|
||||||
|
}
|
||||||
|
|
||||||
|
return dom;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dominates(const PyEO& a, const PyEO& b)
|
||||||
|
{
|
||||||
|
return PyFitness(a.fitness()).dominates(b.fitness());
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream& operator<<(ostream& os, const PyEO& _eo)
|
||||||
|
{
|
||||||
|
os << _eo.to_string();
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pyPop_pickle_suite : boost::python::pickle_suite
|
||||||
|
{
|
||||||
|
static boost::python::tuple getstate(const eoPop<PyEO>& _pop)
|
||||||
|
{
|
||||||
|
boost::python::list entries;
|
||||||
|
for (unsigned i = 0; i != _pop.size(); ++i)
|
||||||
|
entries.append( PyEO_pickle_suite::getstate(_pop[i]) );
|
||||||
|
|
||||||
|
return make_tuple(object(_pop.size()), entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setstate( eoPop<PyEO>& _pop, boost::python::tuple pickled)
|
||||||
|
{
|
||||||
|
int sz = extract<int>(pickled[0]);
|
||||||
|
boost::python::list entries = pickled[1];
|
||||||
|
_pop.resize(sz);
|
||||||
|
for (unsigned i = 0; i != _pop.size(); ++i)
|
||||||
|
PyEO_pickle_suite::setstate(_pop[i], tuple(entries[i]) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
boost::python::str to_string(T& _p)
|
||||||
|
{
|
||||||
|
std::ostrstream os;
|
||||||
|
_p.printOn(os);
|
||||||
|
os << ends;
|
||||||
|
std::string s(os.str());
|
||||||
|
return str(s.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_sort(eoPop<PyEO>& pop) { pop.sort(); }
|
||||||
|
void pop_shuffle(eoPop<PyEO>& pop) { pop.shuffle(); }
|
||||||
|
|
||||||
|
void translate_index_error(index_error const& e)
|
||||||
|
{
|
||||||
|
PyErr_SetString(PyExc_IndexError, e.what.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
PyEO& pop_getitem(eoPop<PyEO>& pop, object key)
|
||||||
|
{
|
||||||
|
extract<int> x(key);
|
||||||
|
if (!x.check())
|
||||||
|
throw index_error("Slicing not allowed");
|
||||||
|
|
||||||
|
int i = x();
|
||||||
|
|
||||||
|
if (static_cast<unsigned>(i) >= pop.size())
|
||||||
|
{
|
||||||
|
throw index_error("Index out of bounds");
|
||||||
|
}
|
||||||
|
|
||||||
|
return pop[i];
|
||||||
|
}
|
||||||
|
void pop_setitem(eoPop<PyEO>& pop, object key, PyEO& value)
|
||||||
|
{
|
||||||
|
|
||||||
|
extract<int> x(key);
|
||||||
|
if (!x.check())
|
||||||
|
throw index_error("Slicing not allowed");
|
||||||
|
|
||||||
|
int i = x();
|
||||||
|
|
||||||
|
if (static_cast<unsigned>(i) >= pop.size())
|
||||||
|
{
|
||||||
|
throw index_error("Index out of bounds");
|
||||||
|
}
|
||||||
|
|
||||||
|
pop[i] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_push_back(eoPop<PyEO>& pop, PyEO& p) { pop.push_back(p); }
|
||||||
|
void pop_resize( eoPop<PyEO>& pop, unsigned i) { pop.resize(i); }
|
||||||
|
|
||||||
|
extern void abstract1();
|
||||||
|
extern void algos();
|
||||||
|
extern void random_numbers();
|
||||||
|
extern void geneticOps();
|
||||||
|
extern void selectOne();
|
||||||
|
extern void continuators();
|
||||||
|
extern void reduce();
|
||||||
|
extern void replacement();
|
||||||
|
extern void selectors();
|
||||||
|
extern void breeders();
|
||||||
|
extern void mergers();
|
||||||
|
extern void valueParam();
|
||||||
|
extern void perf2worth();
|
||||||
|
|
||||||
|
BOOST_PYTHON_MODULE(PyEO)
|
||||||
|
{
|
||||||
|
register_exception_translator<index_error>(&translate_index_error);
|
||||||
|
|
||||||
|
class_<PyEO>("EO")
|
||||||
|
.add_property("fitness", &PyEO::getFitness, &PyEO::setFitness)
|
||||||
|
.add_property("genome", &PyEO::getGenome, &PyEO::setGenome)
|
||||||
|
.def_pickle(PyEO_pickle_suite())
|
||||||
|
.def("invalidate", &PyEO::invalidate)
|
||||||
|
.def("invalid", &PyEO::invalid)
|
||||||
|
.def("__str__", &PyEO::to_string)
|
||||||
|
;
|
||||||
|
|
||||||
|
class_<eoPop<PyEO> >("Pop", init<>() )
|
||||||
|
.def( init< unsigned, eoInit<PyEO>& >() )
|
||||||
|
.def("append", &eoPop<PyEO>::append)
|
||||||
|
.def("__str__", to_string<eoPop<PyEO> >)
|
||||||
|
.def("__len__", &eoPop<PyEO>::size)
|
||||||
|
.def("sort", pop_sort )
|
||||||
|
.def("shuffle", pop_shuffle)
|
||||||
|
.def("__getitem__", pop_getitem, return_internal_reference<>() )
|
||||||
|
.def("__setitem__", pop_setitem)
|
||||||
|
.def("best", &eoPop<PyEO>::best_element, return_internal_reference<>() )
|
||||||
|
.def("push_back", pop_push_back)
|
||||||
|
.def("resize", pop_resize)
|
||||||
|
.def_pickle(pyPop_pickle_suite())
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
// Other definitions in different compilation units,
|
||||||
|
// this to avoid having g++ to choke on the load
|
||||||
|
random_numbers();
|
||||||
|
valueParam();
|
||||||
|
abstract1();
|
||||||
|
geneticOps();
|
||||||
|
selectOne();
|
||||||
|
selectors();
|
||||||
|
perf2worth();
|
||||||
|
continuators();
|
||||||
|
reduce();
|
||||||
|
replacement();
|
||||||
|
breeders();
|
||||||
|
mergers();
|
||||||
|
algos();
|
||||||
|
|
||||||
|
// The traits class
|
||||||
|
class_<PyFitness>("PyFitness");
|
||||||
|
|
||||||
|
def("nObjectives", &PyFitness::nObjectives);
|
||||||
|
def("tol", &PyFitness::tol);
|
||||||
|
def("maximizing", &PyFitness::maximizing);
|
||||||
|
def("setObjectivesSize", &PyFitness::setObjectivesSize);
|
||||||
|
def("setObjectivesValue", &PyFitness::setObjectivesValue);
|
||||||
|
def("dominates", dominates);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// to avoid having to build with libeo.a
|
||||||
|
ostream & operator << ( ostream& _os, const eoPrintable& _o ) {
|
||||||
|
_o.printOn(_os);
|
||||||
|
return _os;
|
||||||
|
};
|
||||||
153
eo/src/pyeo/PyEO.h
Normal file
153
eo/src/pyeo/PyEO.h
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
PyEO
|
||||||
|
|
||||||
|
Copyright (C) 2003 Maarten Keijzer
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PYEO_H
|
||||||
|
#define PYEO_H
|
||||||
|
|
||||||
|
#include <EO.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
|
||||||
|
using namespace boost::python;
|
||||||
|
|
||||||
|
struct index_error { index_error(std::string w) : what(w) {}; std::string what; };
|
||||||
|
|
||||||
|
class PyFitness : public boost::python::object
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
typedef PyFitness fitness_traits; // it's its own traits class :-)
|
||||||
|
|
||||||
|
PyFitness() : object() {}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
PyFitness(const T& o) : object(o) {}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned nObjectives() { return objective_info.size(); }
|
||||||
|
static double tol() { return 1e-6; }
|
||||||
|
static bool maximizing(int which) { return objective_info[which] > 0; }
|
||||||
|
|
||||||
|
static void setObjectivesSize(int sz) { objective_info.resize(sz); }
|
||||||
|
static void setObjectivesValue(unsigned which, int value)
|
||||||
|
{
|
||||||
|
if (which >= objective_info.size())
|
||||||
|
{
|
||||||
|
throw index_error("Too few elements allocated, resize objectives first");
|
||||||
|
}
|
||||||
|
|
||||||
|
objective_info[which] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<int> objective_info;
|
||||||
|
|
||||||
|
bool dominates(const PyFitness& oth) const;
|
||||||
|
|
||||||
|
double operator[](int i) const
|
||||||
|
{
|
||||||
|
extract<double> x(object::operator[](i));
|
||||||
|
|
||||||
|
if (!x.check())
|
||||||
|
throw runtime_error("PyFitness: does not contain doubles");
|
||||||
|
return x();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const PyFitness& other) const
|
||||||
|
{
|
||||||
|
if (objective_info.size() == 0)
|
||||||
|
{
|
||||||
|
const object& self = *this;
|
||||||
|
const object& oth = other;
|
||||||
|
return self < oth;
|
||||||
|
}
|
||||||
|
// otherwise use objective_info
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < objective_info.size(); ++i)
|
||||||
|
{
|
||||||
|
double a = objective_info[i] * operator[](i);
|
||||||
|
double b = objective_info[i] * other[i];
|
||||||
|
|
||||||
|
if ( fabs(a - b) > tol())
|
||||||
|
{
|
||||||
|
if (a < b)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator>(const PyFitness& other) const
|
||||||
|
{
|
||||||
|
return other.operator<(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void printOn(ostream& os) const { const object& o = *this; os << o; }
|
||||||
|
//friend ostream& operator<<(ostream& os, const PyFitness& p) { p.printOn(os); return os; }
|
||||||
|
//friend istream& operator>>(istream& is, PyFitness& p) { object o; is >> o; p = o; return is; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PyEO : public EO< PyFitness >
|
||||||
|
{
|
||||||
|
typedef PyFitness Fitness;
|
||||||
|
|
||||||
|
object getFitness() const { return invalid()? Fitness(): fitness(); }
|
||||||
|
void setFitness(object f) { if (f == Fitness()) invalidate(); else fitness(f); }
|
||||||
|
|
||||||
|
object getGenome() const { return genome; }
|
||||||
|
void setGenome(object g) { genome = g; }
|
||||||
|
object genome;
|
||||||
|
|
||||||
|
std::string to_string() const
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
result += extract<const char*>(str(getFitness()));
|
||||||
|
result += ' ';
|
||||||
|
result += extract<const char*>(str(genome));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const PyEO& other) const { return EO<Fitness>::operator<(other); }
|
||||||
|
bool operator>(const PyEO& other) const { return EO<Fitness>::operator>(other); }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ostream& operator<<(ostream& os, const PyEO& _eo);
|
||||||
|
|
||||||
|
struct PyEO_pickle_suite : boost::python::pickle_suite
|
||||||
|
{
|
||||||
|
typedef PyEO::Fitness Fitness;
|
||||||
|
|
||||||
|
static
|
||||||
|
boost::python::tuple getstate(const PyEO& _eo)
|
||||||
|
{
|
||||||
|
return make_tuple(_eo.getFitness(), _eo.genome);
|
||||||
|
}
|
||||||
|
static
|
||||||
|
void setstate(PyEO& _eo, boost::python::tuple pickled)
|
||||||
|
{
|
||||||
|
_eo.setFitness( Fitness(pickled[0]) );
|
||||||
|
_eo.genome = pickled[1];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in a new issue