# 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_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:

@GTree.gpdec(representation="+", color="red")
def gp_add(a, b): return a+b

We’ll got the follow visualization (click to enlarge):

I hope you enjoyed it, I’m currently fixing some bugs, implementing new features, docs and preparing the next release of Pyevolve, which will take some time yet =)

Christian S. Perone

1. Awesome! I’ve been working on resurrecting the old PyGP project (pygp.sf.net), but it’s no where as good as pyevolve.

How are you going to store save the function after compilation is completed?

Best of luck! I’d be VERY interested in helping out on this project.

Best

2. 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 !

3. is there a reason the interface has Java style setters and getters?

# java-style
ga.setMutationRate(0.8)
# python-style
ga.mutation_rate = 0.8

if you really need to call a function you can wrap the attribute using property().

4. 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 !

5. zioLoga says:

Hi! I think your library will be a blessing for my project!
Just a little problem forced me to install Pyevolve manually:
I’ve tried using easy_install on ubuntu jaunty 32 bit but I got this error:
zioLoga@:~$sudo easy_install pyevolve Searching for pyevolve Reading http://pypi.python.org/simple/pyevolve/ Reading http://pyevolve.sourceforge.net Reading https://sourceforge.net/project/showfiles.php?group_id=251160&package_id=307022&release_id=655413 No local packages or download links found for pyevolve error: Could not find suitable distribution for Requirement.parse(‘pyevolve’) zioLoga@loga:~$

6. Strange error zioLoga, what’s your Python version ?

7. zioLoga says:

I have both python 2.6.2 and 2.5 installed.
I now see I have python-dev installed for 2.6.2 version, but not for the 2.5 one. Maybe is this the cause of the problem?

To install pyevolve I downloaded by hand the egg for python 2.6 and issued easy_install Pyevolve-0.5-py2.6.egg at the prompt. It worked fine.

8. I think that the python-dev is the problem, maybe it search for another pattern on the download links, since only you reported this problem. Thank you.

9. Lachlan says:

I am also getting this error: error: Could not find suitable distribution for Requirement.parse(‘pyevolve’)

Jaunty fully up to date with python 2.[4|5|6] from repositories. easy_install, easy_install-2.[4|5|6] all return the same problem.

1. Thank you for reporting Lachlan, it seems that Sourceforge has changed download page and easy_install isn’t getting the links. I’ll fix it now.

1. cvs says:

Hi, how are you coping with “if” in your gp?
Thanks.

1. In what sense are you talking about ? Could you be more specific ?

1. Idris W says:

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.

So how could you have something like a “gp_if”?

10. Jose Luis says:

Hi all,

I got the following error message:

Traceback (most recent call last):
File “/Users/JoseLuis/workspace/PG/src/PyevolveGP.py”, line 4, in
error_accum = Util.ErrorAccumulator()
AttributeError: ‘module’ object has no attribute ‘ErrorAccumulator’

I am using python 2.6.4 under MacOSX and PyevolveGP.py is the file with the code above.

I am not sure If I need to import anything else.

1. 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

1. Jose Luis says:

Thank you.

I was looking for the dev version, but I cann’t to found out. Where can I download it?

Regards

1. Jose Luis says:

Thank you. It works!

11. Chris says:

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.

1. Peter says:

Except that it normally is code which is evolved. Look at any of Koza’s early papers and he talks a lot about Lisp and shows how he evolves the code with restricted terminals etc.

1. And who is saying that GP doesn’t normally evolves code ?

2. I used pyevolve to construct java programs. The nodes return strings:

def gp_add(a, b): return ‘(%s) – (%s)’ % (a, b)
def gp_sub(a, b): return ‘(%s) + (%s)’ % (a, b)
def gp_mul(a, b): return ‘(%s) * (%s)’ % (a, b)

and the returned program is:

code = eval(code_comp)

which was written to a .java file, compiled and run together with my project.

12. Idris W says:

I’m quite excited by this.

What gp_* functions would need to be added to the core for it to be turing complete, I wonder?

1. You don’t need to add every gp_* function to the core, in fact you can use the Python native “operator” module functions, like operator.add, etc… =)

13. Joe says:

How did you generate the Tree view, was that in Interactive mode?

14. Wojciech Waśko says:

Fantastic! Trying it out right now.

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:
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?

15. helloworld says:

Hello, I am python 2.73, when I install pyevolve I got following errors:
$sudo easy_install pyevolve Searching for pyevolve Reading http://pypi.python.org/simple/pyevolve/ Reading http://pyevolve.sourceforge.net No local packages or download links found for pyevolve error: Could not find suitable distribution for Requirement.parse(‘pyevolve’) it’s any wrong with the resource or me? 16. Lam Giang says: Hello, It’s very interesting that GTreeGP can be used to find the needed function. The question is how I can save this function and reuse it in another module. I tried save data from nodes_list, nodes_branch, nodes_leaf to a file and then read from file but it seems not enough Do you have a solution for this, or add some SaveToFile and ReadFromFile for genome 17. Chris says: Hi, I tried using pip without success. Strange since it found it when I searched with pip… I have python 2.7 (OS X) and haven’t had any similar issues with the ~50 packages I have installed.$ pip search pyevolve
Pyevolve – A complete python genetic algorithm framework
$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 /Users/beard/.pip/pip.log 1. Chris, note that you’re searching for “pyevolve” and then you install “Pyevolve” with the “P” in upper case. Try “pip install pyevolve”. 18. Anonymous says: Hi All, Im enthusiastic about pyevolve. 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? Im using Wing 4.1 on Ubuntu termios.error: (25, ‘Inappropriate ioctl for device’) Best wishes Andi 😉 1. Hello Andi, have you tried updating to the 0.6 rc1 release of Pyevole ? Try to run it outside of IDE too. 19. Anonymous says: FYI: I’m still getting the error: Could not find suitable distribution for… in Mac OSX with the Python.org 2.7 interpreter and latest version of easy_install. 20. Francesco says: Hello, I’ve tried to use pip/easy_install, but it doesn’t work in my case:$ pip search pyevolve
Pyevolve – A complete python genetic algorithm framework

$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
No distributions at all found for Pyevolve

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

Anyway, I’ve installed pyevolve-0.6 by using the Ubuntu repository.

21. This is an awesome project, in my PhD I need use GP, and I’ll use this lib. I make some tests and relay works great.

Congratulations for the wonderful job!

22. denson says:

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
error: Could not find suitable distribution for Requirement.parse(‘pyevolve’)

23. sabrina says:

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

1. 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.

24. マイプログラマは | PHPから.NETに移動するために私を納得させる説得しようとしています。 私は常にためのアイデアを嫌っています。しかし、彼は何も少なくtryiongないです&%

25. Kurt says: