Skip to content

Commit

Permalink
Added a __setitem__ method in PrimitiveTree to check user input. Curr…
Browse files Browse the repository at this point in the history
…ently, these verifications cover three common errors :

- Replacing a primitive by another of a different arity
- Appending a subtree to the end without changing the current primitives (this will lead to an "unaccessible" part of the tree, meaning that len(ind) will
return a different value than len(ind[ind.searchSubtree(0)]), and that some part of the tree will _not_ be evaluated, which can be seriously misleading)
- Inserting an incomplete subtree, for instance [add, 1, 2, 3] (considering that add has an arity of 2), which would mess up the tree

A quick testing shows virtually no performance loss over the previous (non-checked) method.

Also fix a small bug in the C version of the Ant simulator.

--HG--
branch : dev
  • Loading branch information
marc.andre.gardner committed Jul 16, 2012
1 parent d59c2e5 commit ff0c6ad
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 2 deletions.
27 changes: 27 additions & 0 deletions deap/gp.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,33 @@ def __deepcopy__(self, memo):
new.__dict__.update(copy.deepcopy(self.__dict__, memo))
return new

def __setitem__(self, key, val):
# Check for most common errors
# Does NOT check for STGP constraints
if isinstance(key, slice):
if (key.start >= len(self)):
raise IndexError, "Invalid slice object (try to assign a %s"\
" in a tree of size %d). Even if this is allowed by the"\
" list object slice setter, this should not be done in"\
" the PrimitiveTree context, as this may lead to an"\
" unpredictable behavior for searchSubtree or evaluate."\
% (key, len(self))
total = val[0].arity
for node in val[1:]:
total += node.arity - 1
if total != 0:
raise ValueError, "Invalid slice assignation : insertion of"\
" an incomplete subtree is not allowed in PrimitiveTree."\
" A tree is defined as incomplete when some nodes cannot"\
" be mapped to any position in the tree, considering the"\
" primitives' arity. For instance, the tree [sub, 4, 5,"\
" 6] is incomplete if the arity of sub is 2, because it"\
" would produce an orphan node (the 6)."
elif val.arity != self[key].arity:
raise ValueError, "Invalid node replacement with a node of a"\
" different arity."
list.__setitem__(self, key, val)

@property
def height(self):
"""Return the height of the tree, or the depth of the
Expand Down
2 changes: 2 additions & 0 deletions examples/gp/ant/AntSimulatorFast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ PyTypeObject AntSimulatorWrapper_Type = {
PyObject* progn(PyObject *self, PyObject *args){
for(Py_ssize_t i = 0; i < PyTuple_Size(args); i++)
PyObject_CallFunctionObjArgs(PyTuple_GET_ITEM(args, i), NULL);
Py_INCREF(Py_None);
return Py_None;
}

static PyMethodDef AntC_functions[] = {
Expand Down
4 changes: 2 additions & 2 deletions examples/gp/ant/buildAntSimFast.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from distutils.core import setup, Extension

module1 = Extension('cAnt',
module1 = Extension('AntC',
sources = ['AntSimulatorFast.cpp'])

setup (name = 'cAnt',
setup (name = 'AntC',
version = '1.0',
description = 'Fast version of the Ant Simulator (aims to replace the AntSimulator class)',
ext_modules = [module1])

0 comments on commit ff0c6ad

Please sign in to comment.