Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make requests for prim in gp.generate fall back to term if needed #53

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tyarkoni
Copy link

Consider this simple gp example:

from deap.gp import PrimitiveSetTyped, genFull, PrimitiveTree
import operator
import random

pset = PrimitiveSetTyped("main", [], float)
pset.addPrimitive(operator.mul, [float, int], float, name='product')
pset.addEphemeralConstant('a_float', lambda: random.uniform(-10, 10), float)
pset.addEphemeralConstant('an_int', lambda: random.random(), int)
expr = genFull(pset, min_=1, max_=2)

The multiplication primitive requires an int as the second argument, which can be easily satisfied by passing the EphemeralConstant 'an_int' as a terminal node. However, as currently implemented, Primitive instances expect to be able to sample randomly from either the primitives or terminals lists (depending on whether the condition check is satisfied). Because there is no Primitive that outputs an int in the above example, we then get the following exception:

  File "/usr/local/lib/python2.7/site-packages/deap/gp.py", line 516, in genFull
    return generate(pset, min_, max_, condition, type_)
  File "/usr/local/lib/python2.7/site-packages/deap/gp.py", line 600, in generate
    prim = random.choice(pset.primitives[type_])
  File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/random.py", line 275, in choice
    return seq[int(self.random() * len(seq))]  # raises IndexError if seq is empty
IndexError: The gp.generate function tried to add a primitive of type '<type 'int'>', but there is none available.

This seems like undesirable behavior, in that it is possible to return a perfectly valid tree by inserting a terminal in place of a primitive (or vice versa). This can be trivially achieved with the minor change in the attached PR. The only potential downside I can see is that this will occasionally override the requested tree structure--e.g., if the user calls genFull(), it may be impossible to return a tree with equal depth at all terminal nodes while still respecting the requested data types. Still, it seems to me like it would be better to return a valid but imperfect tree (perhaps issuing a simultaneous warning) than to break down entirely under a potentially quite common use case. Thoughts?

@r3v1
Copy link

r3v1 commented Jan 23, 2021

Is there someone supervising this pull request? I agree with @tyarkoni and it may be of interest to return an imperfect valid tree instead of just raising an error.

@fmder
Copy link
Member

fmder commented Nov 13, 2021

For current tree generation methods we are firm on tree structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants