Boost logo

Boost :

From: daniel kottow (daniel.kottow_at_[hidden])
Date: 2001-11-27 14:25:30


hi dave,
sorry i am back, but my hill-climbing seems to have failed before the real
hill even started ...
so this time i will start by giving you the big picture:
the genetic-algorithm library i want to python-enable is based on two
objects:
lets call them Genome and Algorithm.
Algorithm maintains a pool of Genomes, calls their objective function and
does the genetic operations like selection, cross-over and such. a typical
(pseudo)coding example would be

float Objective(const Genome &g)
  //return something fancy based on props of g

Genome g(init_props, Objective);
Algorithm a(g, init_props);
for(;;)
  a.step();

AYCC, Algorithm uses an example genome for building the population.
for this, it relies on virtual member functions called clone and copy.
signatures:

virtual Genome *Genome::clone() const;
virtual void Genome::copy(const Genome &g)

which are suppposed to be overriden if you derive your own Genome. it first
clones your example genome to get an initial population and then mainly
uses copy while applying genetic ops.
i thought it would be a nice idea to make Objective() a virtual member
function in a derived class and then expose it to python.

so i did:

void objective(const Genome &g)
{
        ((PyGenome&)g).objective();
}

class PyGenome : public Genome {
        Genome *clone();
        // void copy(const Genome &g); //no need to change anything here,
use base class imp
        virtual float objective();
};

and implemented (trying to use your suggestions):

Genome *Genome::clone() {
   python::ref *pr;
   pr = new python::ref(newPythonUserGenome());
   return
         BOOST_PYTHON_CONVERSION::from_python(pr->get(),
                                                                                  python::type<PyGenome*>());
}

and

python::ref PyGenome::newPythonUserGenome() const {

  return python::callback<python::ref>::call(pyFuncNewGenome.get());
}

where pyFuncNewGenome is a python::ref which must point to the python
constructor (without args) of the concrete python class which implements
the virtual func objective. (see last posting)
i think the rest of the boost::python code (callback stuff and so on) is
pretty straightforward,
as is the python-enabling of Algorithm.
(but if you need to see more, i can tell/send you more, ofcourse)

runtime resume:

the algorithm basically works ok.
BUT: if an object returned by clone is destroyed by C++ i immediately get a
crash.
i understand this behaviour, but i dont know how to change it.

actually, first i did not create a python::ref in heap and this would crash
much earlier
(because the python::ref would go out of scope and destroy the object,
right? )

now its the other way around, python thinks the object lives forever but it
doesnt.

now, i hope you can give me some advice on this, may it either be regarding
the design or technical.
i was very much reminded by this experience how both things should not go
apart,
specially if the environment is new to you (thats me).

greetings, daniel

-- 
Daniel Kottow                                    daniel.kottow_at_[hidden]
Security and Testing Technology                 
http://vision.fhg.de/~daniel
Production Technology Centre                     Pascalstr. 8 - 9
Fraunhofer-Institut IPK Berlin                   D - 10587 Berlin

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk