Genetic Programming meets Python

I’m proud to announce that the new versions of Pyevolve will have Genetic Programming support; after some time fighting with these evil syntax trees, I think I have a very easy and flexible implementation of GP in Python. I was tired to see people giving up and trying to learn how to implement a simple GP using the hermetic libraries for C/C++ and Java (unfortunatelly I’m a Java web developer hehe).

The implementation is still under some tests and optimization, but it’s working nice, here is some details about it:

The implementation has been done in pure Python, so we still have many bonus from this, but unfortunatelly we lost some performance.

The GP core is very very flexible, because it compiles the GP Trees in Python bytecodes to speed the execution of the function. So, you can use even Python objects as terminals, or any possible Python expression. Any Python function can be used too, and you can use all power of Python to create those functions, which will be automatic detected by the framework using the name prefix =)

As you can see in the source-code, you don’t need to bind variables when calling the syntax tree of the individual, you simple use the “getCompiledCode” method which returns the Python compiled function ready to be executed.

Here is a source-code example:

from pyevolve import *
import math
error_accum = Util.ErrorAccumulator()
# This is the functions used by the GP core,
# Pyevolve will automatically detect them
# and the they number of arguments
def gp_add(a, b): return a+b
def gp_sub(a, b): return a-b
def gp_mul(a, b): return a*b
def gp_sqrt(a): return math.sqrt(abs(a))
def eval_func(chromosome):
global error_accum
error_accum.reset()
code_comp = chromosome.getCompiledCode()
for a in xrange(0, 5):
for b in xrange(0, 5):
# The eval will execute a pre-compiled syntax tree
# as a Python expression, and will automatically use
# the "a" and "b" variables (the terminals defined)
evaluated = eval(code_comp)
target = math.sqrt((a*a)+(b*b))
error_accum += (target, evaluated)
return error_accum.getRMSE()
def main_run():
genome = GTree.GTreeGP()
genome.setParams(max_depth=5, method="ramped")
genome.evaluator.set(eval_func)
ga = GSimpleGA.GSimpleGA(genome)
# This method will catch and use every function that
# begins with "gp", but you can also add them manually.
# The terminals are Python variables, you can use the
# ephemeral random consts too, using ephemeral:random.randint(0,2)
# for example.
ga.setParams(gp_terminals = ['a', 'b'],
gp_function_prefix = "gp")
# You can even use a function call as terminal, like "func()"
# and Pyevolve will use the result of the call as terminal
ga.setMinimax(Consts.minimaxType["minimize"])
ga.setGenerations(1000)
ga.setMutationRate(0.08)
ga.setCrossoverRate(1.0)
ga.setPopulationSize(2000)
ga.evolve(freq_stats=5)
print ga.bestIndividual()
if __name__ == "__main__":
main_run()

I’m very happy and testing the possibilities of this GP implementation in Python.

And of course, everything in Pyevolve can be visualized any time you want (click to enlarge):

The visualization is very flexible too, if you use Python decorators to set how functions will be graphical represented, you can have many interesting visualization patterns. If I change the function “gp_add” to:

Hello Ryan, I’m using the code object to keep the code of the compiled expression. I’m still working on the new release, after that, I’m thinking in rewrite Pyevolve in a new version called Pyevolve2, which will break API backw. comp. and adopt some new OO design, but I contact you, I need to take time to prepare the new 0.6 release before. Thank you !

Yes Jack, this is to keep the API compatibility with older versions. Maybe in the future I’ll make a new version which breaks the API comp. following the conventions of PEP 8. But the project have a large documentation, so I think it’s not a problem for now. Thank you !

I think they mean; how could you have program flow statements in the evolved genome? For example, instead of churning out a procedure which executes linearly, you might want loops, conditionals etc. to allow more advanced algorithms to be produced.

Hello Jose ! What version of Pyevolve are you using !? The GP support is only in the development version (which will be the next 0.6 release).
There is a mail-list for Pyevolve users too, if you are interested, feel free to join us: http://groups.google.com/group/pyevolve

Looks like an interesting project, but does if *have* to construct Python programs? GP doesn’t literally mean constructing an executable computer program. It only means the structure being evolved is theoretically unbounded. I’d imagine for 99.99% of GP applications, the last thing you’d want to do is evolve literal code, since 99.99% of the search space would be nonsensical non-working code.

One thing comes to my mind. It would be nice to have some functionality to “reduce” the GPTree to the smallest equivalent form. For example, when I run your sample program, the individual I got was:
Expression: gp_sqrt(gp_sub(b, gp_add(gp_add(gp_mul(a, a), gp_mul(b, b)), b)))
Which is, in fact, equivalent to the following shorter expression (the minus sign comes from abs() in gp_sqrt, which allows it to accept negative values):
Expression: gp_sqrt(- gp_add(gp_mul(a, a), gp_mul(b, b)))

I wonder if such a functionality would belong in pyevolve or not. What do you think?

However, starting my first program (just using the example from the pyevolve website), Im getting the following error and I tried heavily to fix it, but Im out of ideas now. Could anybody please help out?

$ pip install pyevolve
Downloading/unpacking pyevolve
Could not find any downloads that satisfy the requirement pyevolve
No distributions at all found for pyevolve
Storing complete log in /home/redcrow/.pip/pip.log

$ pip install Pyevolve
Downloading/unpacking Pyevolve
Could not find any downloads that satisfy the requirement Pyevolve
No distributions at all found for Pyevolve
Storing complete log in /home/redcrow/.pip/pip.log

After reading the pip.log it seems there’s no available package for my python (version 2.7).

I’m unable to install pyevolve on Ubuntu 12.04.4 LTS with python 2.7.3. I get the following error:

sudo easy_install pyevolve
Searching for pyevolve
Reading http://pypi.python.org/simple/pyevolve/
No local packages or download links found for pyevolve
error: Could not find suitable distribution for Requirement.parse(‘pyevolve’)

I’m new to Python and GP and I’am trying to print the best individual’s expression in order to evaluate it and compare the result with the target. Is there a built in function of Pyevolve that does this? because as I try to import the result to a file.csv, I get the tree expression which is unsuitable for later evaluation.
Any help would be greatly appreciated

Hello Sabrina, there are two methods: getSExpression() and getPreOrderExpression(), there is also the method getCompiledCode() that will return a Python compiled function of that individual expression.