简体   繁体   中英

Saving all nodes in binary tree based Python program

I have been trying to add a way of storing and retrieving knowledge gained by the program animal.py , which is a "20 questions" learning algorithm that works via a binary decision tree. (Please click link to see the original program)

To the original program, I have added the state "up" to each node, to point to the parent of a node in the decision tree, in order to make it easier to move both up and down the tree. I have also used regex to change all non-alphanumeric user input to spaces, so the user cannot confuse my two new functions:

def know(know):
    #Load preset knowledge
    p=node("")
    knowledge=p
    for char in know:
            if char not in "+-":p.question+=char
            if char=="+":
                    p.right=node("")
                    p.right.up=p
                    p.left=node("")
                    p.left.up=p
                    p=p.right
            if char=="-": p=p.up.left
    return knowledge

def output(node,accum=""):
    #Output all knowledge
    accum=accum+node.question
    if node.right!= None : accum=output(node.right,accum+"+")
    if node.left!= None : accum=output(node.left,accum+"-")
    return accum

The function "output" is designed to return the complete tree underneath the node passed to it as a single string, with "+" and "-" characters indicating which node the string is following down. The function "know" is supposed to take a string previously created by "output", create the binary decision tree and return a pointer to the top node. This is the part that is not quite working that I cannot figure out. (Currently, I am inputing the initial knowledge string directly into the program source: loading and saving files will be added later, and seems a trivial task)

Eg: output(know('mineral+crystal+quartz-obsidian-nothing')) returns: 'mineral+crystal+quartz-obsidiannothing-'

where it should return the original string: 'mineral+crystal+quartz-obsidian-nothing'

I am sure this should work (in theory), but I have hit a wall and am really lost as to why it is not.

Is my idea wrong, or just my attempt to implement it? Is there a better way to store the created decision tree from the original program?

I am an avid reader but first time poster to stackoverflow, and am in awe of the talent on this site, so I very much look forward your ideas.

The pickle module can serialize and unserialize complicated structures. This should be as simple as:

with open('animal.dat', 'w') as outf:
    pickle.dump(knowledge, outf)

and

with open('animal.dat', 'r') as inf:
    knowledge = pickle.load(inf)

As they say, "the batteries are included" so learning the standard library makes hard things easy, even flying .

Per request, I was unable to find my implementation of "guess the animal" but I did find an archived pickle file generated by it. It is worth noting that I didn't need the original app to be able to interpret it:

>>> import pickle
>>> with open('animal.pickle') as inf:
...     animals = pickle.load(inf)
... 
>>> import pprint
>>> pprint.pprint(animals)
['is it fuzzy',
 ['does it have a tail',
  ['is it a pack hunter',
   'dog',
   ['does it have thumbs',
    'lemur',
    ['Does it have a bushy tail',
     'chipmunk',
     ['Does it have a horn', 'rhinoceros', 'cat']]]],
  'chimp'],
 ['can it breathe air',
  ['Does it have feathers',
   'cockatoo',
   ['Does it have 8 legs', 'spider', 'iguana']],
  'catfish']]

The implementation of the program that creates this tree-as-nested-lists is left as an exercise for the reader. To my recollection, it was about the same length and general approach as the one linked in the question and it will get you familiar with list manipulation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM