I know tree is a well studied structure.
I’m writing a program that randomly generates many expression trees and then sorts and selects by a fitness attribute.
I have a class MakeTreeInOrder() that turns the tree into a string that ‘eval’ can evaluate.
but it gets called many many times, and should be optimized for time.
below is a function that builds a tree that adds successive numbers to use as a test.
I was wondering if there is an optimized way to evaluate an expression that is in a tree structure. I figured that
that it’s used quite a bit and somebodys already done this.
import itertools
from collections import namedtuple
#Further developing Torsten Marek's second suggestion
KS = itertools.count()
Node = namedtuple("Node", ["cargo", "args"])
def build_nodes (depth = 5):
if (depth <= 0):
this_node = Node((str(KS.next())), [None, None])
return this_node
else:
this_node = Node('+', [])
this_node.args.extend(
build_nodes(depth = depth - (i + 1))
for i in range(2))
return this_node
The following is the code that I think can be made a lot faster. And I was hoping for some ideas.
class MakeTreeInOrder(object):
def __init__(self, node):
object.__init__(self)
self.node = node
self.str = ''
def makeit(self, nnode = ''):
if nnode == '':
nnode = self.node
if nnode == None: return
self.str +='('
self.makeit(nnode.args[0])
self.str += nnode.cargo
self.makeit(nnode.args[1])
self.str+=')'
return self.str
def Main():
this_tree = build_nodes()
expression_generator = MakeTreeInOrder(this_tree)
this_expression = expression_generator.makeit()
print this_expression
print eval(this_expression)
if __name__ == '__main__':
rresult = Main()
Adding a touch of object orientation here makes things simpler. Have subclasses of Node for each thing in your tree, and use an ‘eval’ method to evaluate them.
To evaluate the tree, just call .eval() on the top level node.
I also added a
__str__method to convert the tree to a string so you can see how this generalizes to other tree functions. It just does ‘+’ at the moment, but hopefully it’s clear how to extend this to the full range of arithmetic operations.