Python'da bir ağacı nasıl uygulayabilirim?


Yanıtlar:


236

anytree

Https://pypi.python.org/pypi/anytree'yi tavsiye ederim (Ben yazarım)

Misal

from anytree import Node, RenderTree

udo = Node("Udo")
marc = Node("Marc", parent=udo)
lian = Node("Lian", parent=marc)
dan = Node("Dan", parent=udo)
jet = Node("Jet", parent=dan)
jan = Node("Jan", parent=dan)
joe = Node("Joe", parent=dan)

print(udo)
Node('/Udo')
print(joe)
Node('/Udo/Dan/Joe')

for pre, fill, node in RenderTree(udo):
    print("%s%s" % (pre, node.name))
Udo
├── Marc
   └── Lian
└── Dan
    ├── Jet
    ├── Jan
    └── Joe

print(dan.children)
(Node('/Udo/Dan/Jet'), Node('/Udo/Dan/Jan'), Node('/Udo/Dan/Joe'))

Özellikleri

anytree ayrıca güçlü bir API'ye sahiptir:

  • basit ağaç oluşturma
  • basit ağaç modifikasyonu
  • ön sipariş ağacı yinelemesi
  • sipariş sonrası ağaç yinelemesi
  • göreli ve mutlak düğüm yollarını çöz
  • bir düğümden diğerine yürüme.
  • ağaç işleme (yukarıdaki örneğe bakın)
  • düğüm takma / ayırma bağlantıları

31
En iyi cevap, diğerleri tekerleği yeniden keşfediyor.
Ondrej

66
Yanıtınızda önerdiğiniz paketin yazarı olduğunuzu açıklamak iyi bir formdur.
John Y

3
@ c0fec0de seni seviyorum !!!! Bu kütüphane şaşırtıcı, hatta bir görselleştirme işlevine sahip
layser

2
@Ondrej de diğer cevaplar daha az bağımlılık ve orijinal soru yerleşik veri yapıları hakkında sordu. anytreeMuhtemelen harika bir kütüphane olsa da, bu bir Node.js sorusu değil, bir python sorusudur.
Rob Rose

Bu cevapla Google üzerinden karşılaştım. Bu kütüphane gerçekten çok güzel. Özellikle herhangi bir nesnenin ağacı yapmak için mixin sınıfını kullanma yeteneğini seviyorum!
Rÿck Nöthing

104

Python, Java'nın yaptığı gibi oldukça geniş kapsamlı "yerleşik" veri yapılarına sahip değildir. Ancak, Python dinamik olduğu için, genel bir ağaç oluşturmak kolaydır. Örneğin, bir ikili ağaç şunlar olabilir:

class Tree:
    def __init__(self):
        self.left = None
        self.right = None
        self.data = None

Bu şekilde kullanabilirsiniz:

root = Tree()
root.data = "root"
root.left = Tree()
root.left.data = "left"
root.right = Tree()
root.right.data = "right"

109
Bu, yararlı bir ağaç uygulaması yapma hakkında çok fazla açıklama yapmaz.
Mike Graham

14
Soru Python3 ile etiketlendi, class Treeo zaman nesneden türetmeye gerek yok
cfi

3
@cfi Türetmek objectbazen sadece bir kılavuzdur: Bir sınıf başka hiçbir temel sınıftan miras alırsa, nesneyi açıkça miras alır. Bu, iç içe sınıflar için de geçerlidir. Bkz. Google Python Stil Kılavuzu
Konrad Reiche

16
@platzhirsch: Lütfen kılavuzu tamamen okuyup alıntılayın: Google, bunun Python 2 kodunun Py3 ile uyumluluğu geliştirmek için beklendiği ve önerilen şekilde çalışması için gerekli olduğunu açıkça belirtmektedir. Burada Py3 kodundan bahsediyoruz. Ekstra, eski yazım yapmaya gerek yoktur.
cfi

13
Bu bir ikili ağaç, istendiği gibi genel bir ağaç değil.
Michael Dorner

49

Genel bir ağaç, sıfır veya daha fazla alt öğeye sahip bir düğümdür, her biri uygun (ağaç) bir düğümdür. İkili ağaçla aynı değildir, her ikisi de bir terminolojiyi paylaşmasına rağmen farklı veri yapılarıdır.

Python'da jenerik ağaçlar için herhangi bir yerleşik veri yapısı yoktur, ancak sınıflarla kolayca uygulanabilir.

class Tree(object):
    "Generic tree node."
    def __init__(self, name='root', children=None):
        self.name = name
        self.children = []
        if children is not None:
            for child in children:
                self.add_child(child)
    def __repr__(self):
        return self.name
    def add_child(self, node):
        assert isinstance(node, Tree)
        self.children.append(node)
#    *
#   /|\
#  1 2 +
#     / \
#    3   4
t = Tree('*', [Tree('1'),
               Tree('2'),
               Tree('+', [Tree('3'),
                          Tree('4')])])

Şaşırtıcı, bu da kolayca bir grafik olarak kullanılabilir! Gördüğüm tek sorun: Sol düğümü sağ düğümden nasıl ayırabilirim?
Angelo Polotto

3
Çocuk endeksine göre. Bu durumda sol daima çocuk olacaktır [0].
Freund Allein


21
class Node:
    """
    Class Node
    """
    def __init__(self, value):
        self.left = None
        self.data = value
        self.right = None

class Tree:
    """
    Class tree will provide a tree as well as utility functions.
    """

    def createNode(self, data):
        """
        Utility function to create a node.
        """
        return Node(data)

    def insert(self, node , data):
        """
        Insert function will insert a node into tree.
        Duplicate keys are not allowed.
        """
        #if tree is empty , return a root node
        if node is None:
            return self.createNode(data)
        # if data is smaller than parent , insert it into left side
        if data < node.data:
            node.left = self.insert(node.left, data)
        elif data > node.data:
            node.right = self.insert(node.right, data)

        return node


    def search(self, node, data):
        """
        Search function will search a node into tree.
        """
        # if root is None or root is the search data.
        if node is None or node.data == data:
            return node

        if node.data < data:
            return self.search(node.right, data)
        else:
            return self.search(node.left, data)



    def deleteNode(self,node,data):
        """
        Delete function will delete a node into tree.
        Not complete , may need some more scenarion that we can handle
        Now it is handling only leaf.
        """

        # Check if tree is empty.
        if node is None:
            return None

        # searching key into BST.
        if data < node.data:
            node.left = self.deleteNode(node.left, data)
        elif data > node.data:
            node.right = self.deleteNode(node.right, data)
        else: # reach to the node that need to delete from BST.
            if node.left is None and node.right is None:
                del node
            if node.left == None:
                temp = node.right
                del node
                return  temp
            elif node.right == None:
                temp = node.left
                del node
                return temp

        return node






    def traverseInorder(self, root):
        """
        traverse function will print all the node in the tree.
        """
        if root is not None:
            self.traverseInorder(root.left)
            print root.data
            self.traverseInorder(root.right)

    def traversePreorder(self, root):
        """
        traverse function will print all the node in the tree.
        """
        if root is not None:
            print root.data
            self.traversePreorder(root.left)
            self.traversePreorder(root.right)

    def traversePostorder(self, root):
        """
        traverse function will print all the node in the tree.
        """
        if root is not None:
            self.traversePostorder(root.left)
            self.traversePostorder(root.right)
            print root.data


def main():
    root = None
    tree = Tree()
    root = tree.insert(root, 10)
    print root
    tree.insert(root, 20)
    tree.insert(root, 30)
    tree.insert(root, 40)
    tree.insert(root, 70)
    tree.insert(root, 60)
    tree.insert(root, 80)

    print "Traverse Inorder"
    tree.traverseInorder(root)

    print "Traverse Preorder"
    tree.traversePreorder(root)

    print "Traverse Postorder"
    tree.traversePostorder(root)


if __name__ == "__main__":
    main()

3
Kodunuzu ve uygulamanızı tanıtmak için bazı notlar ekleyebilir misiniz?
Michele d'Amico

Yardımcı işlevler ile tam Binary Tree uygulaması için teşekkürler. Python 2 olduğundan, Python 3 sürümüne ihtiyaç duyan insanlar için İkili Ağaç uygulaması (Py3) için bir özgeçmiş oluşturdum .
CᴴᴀZ

16

Yerleşik ağaçlar yoktur, ancak List'teki bir Düğüm türünü alt sınıflandırarak ve geçiş yöntemlerini yazarak kolayca bir tane oluşturabilirsiniz. Bunu yaparsanız, bisect'i yararlı buldum .

PyPi'de göz atabileceğiniz birçok uygulama da var .

Doğru hatırlıyorsam, Python standart lib, .NET temel sınıf kitaplığıyla aynı nedenden ötürü ağaç veri yapılarını içermez: belleğin yeri azalır, bu da daha fazla önbellek kaybına neden olur. Modern işlemcilerde, önbelleğe büyük miktarda bellek getirmek genellikle daha hızlıdır ve "işaretçi açısından zengin" veri yapıları bu avantajı olumsuz etkiler.


2
FYI: İnterwebler Boost'a karşı nefretle sıvalı. Görünüşe göre, özellikle destek kesildiği için başa çıkmak için BÜYÜK bir acı olması gerekiyordu. Bu yüzden bundan uzak
inspectorG4dget

Teşekkürler. Şahsen herhangi bir sorun yaşamadım, ancak yanıltıcı olmak istemiyorum, bu referansı kaldırdım.
Justin R.

11

Köklü bir ağacı sözlük olarak uyguladım {child:parent}. Örneğin, kök düğümünde 0bir ağaç şöyle görünebilir:

tree={1:0, 2:0, 3:1, 4:2, 5:3}

Bu yapı, üzerinde çalıştığım problemle ilgili olan herhangi bir düğümden köke giden bir yol boyunca yukarı gitmeyi oldukça kolaylaştırdı.


1
Cevabı görene kadar bunu yapmayı düşünüyordum. Bir ağaç iki çocuklu bir ebeveyn olduğundan ve aşağı gitmek istiyorsanız, bunu yapabilirsiniz {parent:[leftchild,rightchild]}.
JFA

1
Başka bir yol, listedeki ilk (veya daha fazla) öğenin düğüm değeri olduğu liste listelerini kullanmaktır ve aşağıdaki iç içe iki liste sol ve sağ alt ağaçlarını (veya n-ary ağacı için daha fazla) temsil eder.
pepr

9

Greg Hewgill'in cevabı harika, ancak seviye başına daha fazla düğüme ihtiyacınız varsa, bunları oluşturmak için bir liste | sözlüğü kullanabilirsiniz: Ve sonra bunlara ad veya siparişe (id gibi) erişmek için yöntemi kullanın

class node(object):
    def __init__(self):
        self.name=None
        self.node=[]
        self.otherInfo = None
        self.prev=None
    def nex(self,child):
        "Gets a node by number"
        return self.node[child]
    def prev(self):
        return self.prev
    def goto(self,data):
        "Gets the node by name"
        for child in range(0,len(self.node)):
            if(self.node[child].name==data):
                return self.node[child]
    def add(self):
        node1=node()
        self.node.append(node1)
        node1.prev=self
        return node1

Şimdi sadece bir kök oluşturun ve oluşturun: ex:

tree=node()  #create a node
tree.name="root" #name it root
tree.otherInfo="blue" #or what ever 
tree=tree.add() #add a node to the root
tree.name="node1" #name it

    root
   /
child1

tree=tree.add()
tree.name="grandchild1"

       root
      /
   child1
   /
grandchild1

tree=tree.prev()
tree=tree.add()
tree.name="gchild2"

          root
           /
        child1
        /    \
grandchild1 gchild2

tree=tree.prev()
tree=tree.prev()
tree=tree.add()
tree=tree.name="child2"

              root
             /   \
        child1  child2
       /     \
grandchild1 gchild2


tree=tree.prev()
tree=tree.goto("child1") or tree=tree.nex(0)
tree.name="changed"

              root
              /   \
         changed   child2
        /      \
  grandchild1  gchild2

Bu işin nasıl yapılacağını anlamaya başlamanız için yeterli olmalı


Bu cevapta bir şey eksik, son 2 gündür bu çözümü deniyordum ve nesne ekleme yönteminde mantıklı bir akışınız olduğunu düşünüyorum. Cevabımı bu soruya göndereceğim, lütfen kontrol edin ve yardımcı olup olamayacağımı bana bildirin.
MAULIK MODI

8
class Tree(dict):
    """A tree implementation using python's autovivification feature."""
    def __missing__(self, key):
        value = self[key] = type(self)()
        return value

    #cast a (nested) dict to a (nested) Tree class
    def __init__(self, data={}):
        for k, data in data.items():
            if isinstance(data, dict):
                self[k] = type(self)(data)
            else:
                self[k] = data

sözlük olarak çalışır, ancak istediğiniz kadar yuvalanmış dikte sağlar. Takip etmeyi dene:

your_tree = Tree()

your_tree['a']['1']['x']  = '@'
your_tree['a']['1']['y']  = '#'
your_tree['a']['2']['x']  = '$'
your_tree['a']['3']       = '%'
your_tree['b']            = '*'

iç içe geçmiş bir dikte sunacak ... bu gerçekten bir ağaç gibi çalışıyor

{'a': {'1': {'x': '@', 'y': '#'}, '2': {'x': '$'}, '3': '%'}, 'b': '*'}

... Zaten bir kararınız varsa, her seviyeyi bir ağaca atacaktır:

d = {'foo': {'amy': {'what': 'runs'} } }
tree = Tree(d)

print(d['foo']['amy']['what']) # returns 'runs'
d['foo']['amy']['when'] = 'now' # add new branch

Bu şekilde, her bir dikte seviyesini istediğiniz gibi düzenlemeye / eklemeye / kaldırmaya devam edebilirsiniz. Geçiş vb. İçin tüm dikt yöntemleri hala geçerlidir.


2
dictBunun yerine uzatmayı seçmenizin bir nedeni var mı defaultdict? Testlerimden, dikte defaultdictyerine genişletme ve ardından self.default_factory = type(self)init'in üstüne ekleme aynı şekilde çalışmalıdır.
Rob Rose

muhtemelen burada bir şey eksik, bu yapıda nasıl gezinirsiniz? çocuklardan ebeveynlere veya kardeşlere gitmek çok zor görünüyor
Stormsson

6

Yuvalanmış dikte kullanarak ağaçlar uyguladım. Yapması oldukça kolay ve benim için oldukça büyük veri kümeleriyle çalıştı. Aşağıda bir örnek yayınladım ve Google kodunda daha fazlasını görebilirsiniz

  def addBallotToTree(self, tree, ballotIndex, ballot=""):
    """Add one ballot to the tree.

    The root of the tree is a dictionary that has as keys the indicies of all 
    continuing and winning candidates.  For each candidate, the value is also
    a dictionary, and the keys of that dictionary include "n" and "bi".
    tree[c]["n"] is the number of ballots that rank candidate c first.
    tree[c]["bi"] is a list of ballot indices where the ballots rank c first.

    If candidate c is a winning candidate, then that portion of the tree is
    expanded to indicate the breakdown of the subsequently ranked candidates.
    In this situation, additional keys are added to the tree[c] dictionary
    corresponding to subsequently ranked candidates.
    tree[c]["n"] is the number of ballots that rank candidate c first.
    tree[c]["bi"] is a list of ballot indices where the ballots rank c first.
    tree[c][d]["n"] is the number of ballots that rank c first and d second.
    tree[c][d]["bi"] is a list of the corresponding ballot indices.

    Where the second ranked candidates is also a winner, then the tree is 
    expanded to the next level.  

    Losing candidates are ignored and treated as if they do not appear on the 
    ballots.  For example, tree[c][d]["n"] is the total number of ballots
    where candidate c is the first non-losing candidate, c is a winner, and
    d is the next non-losing candidate.  This will include the following
    ballots, where x represents a losing candidate:
    [c d]
    [x c d]
    [c x d]
    [x c x x d]

    During the count, the tree is dynamically updated as candidates change
    their status.  The parameter "tree" to this method may be the root of the
    tree or may be a sub-tree.
    """

    if ballot == "":
      # Add the complete ballot to the tree
      weight, ballot = self.b.getWeightedBallot(ballotIndex)
    else:
      # When ballot is not "", we are adding a truncated ballot to the tree,
      # because a higher-ranked candidate is a winner.
      weight = self.b.getWeight(ballotIndex)

    # Get the top choice among candidates still in the running
    # Note that we can't use Ballots.getTopChoiceFromWeightedBallot since
    # we are looking for the top choice over a truncated ballot.
    for c in ballot:
      if c in self.continuing | self.winners:
        break # c is the top choice so stop
    else:
      c = None # no candidates left on this ballot

    if c is None:
      # This will happen if the ballot contains only winning and losing
      # candidates.  The ballot index will not need to be transferred
      # again so it can be thrown away.
      return

    # Create space if necessary.
    if not tree.has_key(c):
      tree[c] = {}
      tree[c]["n"] = 0
      tree[c]["bi"] = []

    tree[c]["n"] += weight

    if c in self.winners:
      # Because candidate is a winner, a portion of the ballot goes to
      # the next candidate.  Pass on a truncated ballot so that the same
      # candidate doesn't get counted twice.
      i = ballot.index(c)
      ballot2 = ballot[i+1:]
      self.addBallotToTree(tree[c], ballotIndex, ballot2)
    else:
      # Candidate is in continuing so we stop here.
      tree[c]["bi"].append(ballotIndex)

5

Sitemde bir Python [3] ağaç uygulaması yayınladım: http://www.quesucede.com/page/show/id/python_3_tree_implementation .

Umarım faydalıdır,

Tamam, işte kod:

import uuid

def sanitize_id(id):
    return id.strip().replace(" ", "")

(_ADD, _DELETE, _INSERT) = range(3)
(_ROOT, _DEPTH, _WIDTH) = range(3)

class Node:

    def __init__(self, name, identifier=None, expanded=True):
        self.__identifier = (str(uuid.uuid1()) if identifier is None else
                sanitize_id(str(identifier)))
        self.name = name
        self.expanded = expanded
        self.__bpointer = None
        self.__fpointer = []

    @property
    def identifier(self):
        return self.__identifier

    @property
    def bpointer(self):
        return self.__bpointer

    @bpointer.setter
    def bpointer(self, value):
        if value is not None:
            self.__bpointer = sanitize_id(value)

    @property
    def fpointer(self):
        return self.__fpointer

    def update_fpointer(self, identifier, mode=_ADD):
        if mode is _ADD:
            self.__fpointer.append(sanitize_id(identifier))
        elif mode is _DELETE:
            self.__fpointer.remove(sanitize_id(identifier))
        elif mode is _INSERT:
            self.__fpointer = [sanitize_id(identifier)]

class Tree:

    def __init__(self):
        self.nodes = []

    def get_index(self, position):
        for index, node in enumerate(self.nodes):
            if node.identifier == position:
                break
        return index

    def create_node(self, name, identifier=None, parent=None):

        node = Node(name, identifier)
        self.nodes.append(node)
        self.__update_fpointer(parent, node.identifier, _ADD)
        node.bpointer = parent
        return node

    def show(self, position, level=_ROOT):
        queue = self[position].fpointer
        if level == _ROOT:
            print("{0} [{1}]".format(self[position].name,
                                     self[position].identifier))
        else:
            print("\t"*level, "{0} [{1}]".format(self[position].name,
                                                 self[position].identifier))
        if self[position].expanded:
            level += 1
            for element in queue:
                self.show(element, level)  # recursive call

    def expand_tree(self, position, mode=_DEPTH):
        # Python generator. Loosly based on an algorithm from 'Essential LISP' by
        # John R. Anderson, Albert T. Corbett, and Brian J. Reiser, page 239-241
        yield position
        queue = self[position].fpointer
        while queue:
            yield queue[0]
            expansion = self[queue[0]].fpointer
            if mode is _DEPTH:
                queue = expansion + queue[1:]  # depth-first
            elif mode is _WIDTH:
                queue = queue[1:] + expansion  # width-first

    def is_branch(self, position):
        return self[position].fpointer

    def __update_fpointer(self, position, identifier, mode):
        if position is None:
            return
        else:
            self[position].update_fpointer(identifier, mode)

    def __update_bpointer(self, position, identifier):
        self[position].bpointer = identifier

    def __getitem__(self, key):
        return self.nodes[self.get_index(key)]

    def __setitem__(self, key, item):
        self.nodes[self.get_index(key)] = item

    def __len__(self):
        return len(self.nodes)

    def __contains__(self, identifier):
        return [node.identifier for node in self.nodes
                if node.identifier is identifier]

if __name__ == "__main__":

    tree = Tree()
    tree.create_node("Harry", "harry")  # root node
    tree.create_node("Jane", "jane", parent = "harry")
    tree.create_node("Bill", "bill", parent = "harry")
    tree.create_node("Joe", "joe", parent = "jane")
    tree.create_node("Diane", "diane", parent = "jane")
    tree.create_node("George", "george", parent = "diane")
    tree.create_node("Mary", "mary", parent = "diane")
    tree.create_node("Jill", "jill", parent = "george")
    tree.create_node("Carol", "carol", parent = "jill")
    tree.create_node("Grace", "grace", parent = "bill")
    tree.create_node("Mark", "mark", parent = "jane")

    print("="*80)
    tree.show("harry")
    print("="*80)
    for node in tree.expand_tree("harry", mode=_WIDTH):
        print(node)
    print("="*80)

4

Birinin bunu yapmak için daha basit bir yola ihtiyacı varsa, ağaç yalnızca özyinelemeli iç içe bir listedir (küme yıkanabilir olmadığından):

[root, [child_1, [[child_11, []], [child_12, []]], [child_2, []]]]

Her dal bir çift ise: [ object, [children] ]
ve her yaprak bir çift:[ object, [] ]

Ancak yöntemlerle bir sınıfa ihtiyacınız varsa, anytree'yi kullanabilirsiniz.


1

Hangi işlemlere ihtiyacınız var? Python'da bisect modülüyle bir diksiyon veya liste kullanarak genellikle iyi bir çözüm vardır.

PyPI üzerinde çok, çok sayıda ağaç uygulaması vardır ve birçok ağaç türü kendinizi saf Python'da uygulamak için neredeyse önemsizdir. Ancak, bu nadiren gereklidir.


0

Başka bir ağaç uygulaması, Bruno'nun cevabına gevşek bir şekilde dayanıyor :

class Node:
    def __init__(self):
        self.name: str = ''
        self.children: List[Node] = []
        self.parent: Node = self

    def __getitem__(self, i: int) -> 'Node':
        return self.children[i]

    def add_child(self):
        child = Node()
        self.children.append(child)
        child.parent = self
        return child

    def __str__(self) -> str:
        def _get_character(x, left, right) -> str:
            if x < left:
                return '/'
            elif x >= right:
                return '\\'
            else:
                return '|'

        if len(self.children):
            children_lines: Sequence[List[str]] = list(map(lambda child: str(child).split('\n'), self.children))
            widths: Sequence[int] = list(map(lambda child_lines: len(child_lines[0]), children_lines))
            max_height: int = max(map(len, children_lines))
            total_width: int = sum(widths) + len(widths) - 1
            left: int = (total_width - len(self.name) + 1) // 2
            right: int = left + len(self.name)

            return '\n'.join((
                self.name.center(total_width),
                ' '.join(map(lambda width, position: _get_character(position - width // 2, left, right).center(width),
                             widths, accumulate(widths, add))),
                *map(
                    lambda row: ' '.join(map(
                        lambda child_lines: child_lines[row] if row < len(child_lines) else ' ' * len(child_lines[0]),
                        children_lines)),
                    range(max_height))))
        else:
            return self.name

Ve nasıl kullanılacağına dair bir örnek:

tree = Node()
tree.name = 'Root node'
tree.add_child()
tree[0].name = 'Child node 0'
tree.add_child()
tree[1].name = 'Child node 1'
tree.add_child()
tree[2].name = 'Child node 2'
tree[1].add_child()
tree[1][0].name = 'Grandchild 1.0'
tree[2].add_child()
tree[2][0].name = 'Grandchild 2.0'
tree[2].add_child()
tree[2][1].name = 'Grandchild 2.1'
print(tree)

Hangi çıktılar:

                        Kök düğümü                        
     / / \              
Çocuk düğümü 0 Çocuk düğümü 1 Çocuk düğümü 2        
                   | / \       
             Torun 1.0 Torun 2.0 Torun 2.1

0

Networkx kütüphanesini öneririm .

NetworkX, karmaşık ağların yapısı, dinamikleri ve işlevlerinin oluşturulması, manipülasyonu ve incelenmesi için bir Python paketidir.

Bir ağaç inşa etmeye örnek:

import networkx as nx
G = nx.Graph()
G.add_edge('A', 'B')
G.add_edge('B', 'C')
G.add_edge('B', 'D')
G.add_edge('A', 'E')
G.add_edge('E', 'F')

" Genel ağaç" ile ne demek istediğinizden emin değilim ,
ancak kütüphane her düğümün herhangi bir yıkanabilir nesne olmasını sağlar ve her düğümün sahip olduğu çocuk sayısı konusunda herhangi bir kısıtlama yoktur.

Kütüphane ayrıca ağaçlarla ilgili grafik algoritmaları ve görüntüleme yetenekleri de sağlar.


-2

Bir ağaç veri yapısı oluşturmak istiyorsanız, önce treeElement nesnesini oluşturmanız gerekir. TreeElement nesnesini oluşturursanız, ağacınızın nasıl davranacağına karar verebilirsiniz.

Bunu yapmak için TreeElement sınıfı:

class TreeElement (object):

def __init__(self):
    self.elementName = None
    self.element = []
    self.previous = None
    self.elementScore = None
    self.elementParent = None
    self.elementPath = []
    self.treeLevel = 0

def goto(self, data):
    for child in range(0, len(self.element)):
        if (self.element[child].elementName == data):
            return self.element[child]

def add(self):

    single_element = TreeElement()
    single_element.elementName = self.elementName
    single_element.previous = self.elementParent
    single_element.elementScore = self.elementScore
    single_element.elementPath = self.elementPath
    single_element.treeLevel = self.treeLevel

    self.element.append(single_element)

    return single_element

Şimdi, ağacı oluşturmak için bu elemanı kullanmalıyız, bu örnekte A * ağacı kullanıyorum.

class AStarAgent(Agent):
# Initialization Function: Called one time when the game starts
def registerInitialState(self, state):
    return;

# GetAction Function: Called with every frame
def getAction(self, state):

    # Sorting function for the queue
    def sortByHeuristic(each_element):

        if each_element.elementScore:
            individual_score = each_element.elementScore[0][0] + each_element.treeLevel
        else:
            individual_score = admissibleHeuristic(each_element)

        return individual_score

    # check the game is over or not
    if state.isWin():
        print('Job is done')
        return Directions.STOP
    elif state.isLose():
        print('you lost')
        return Directions.STOP

    # Create empty list for the next states
    astar_queue = []
    astar_leaf_queue = []
    astar_tree_level = 0
    parent_tree_level = 0

    # Create Tree from the give node element
    astar_tree = TreeElement()
    astar_tree.elementName = state
    astar_tree.treeLevel = astar_tree_level
    astar_tree = astar_tree.add()

    # Add first element into the queue
    astar_queue.append(astar_tree)

    # Traverse all the elements of the queue
    while astar_queue:

        # Sort the element from the queue
        if len(astar_queue) > 1:
            astar_queue.sort(key=lambda x: sortByHeuristic(x))

        # Get the first node from the queue
        astar_child_object = astar_queue.pop(0)
        astar_child_state = astar_child_object.elementName

        # get all legal actions for the current node
        current_actions = astar_child_state.getLegalPacmanActions()

        if current_actions:

            # get all the successor state for these actions
            for action in current_actions:

                # Get the successor of the current node
                next_state = astar_child_state.generatePacmanSuccessor(action)

                if next_state:

                    # evaluate the successor states using scoreEvaluation heuristic
                    element_scored = [(admissibleHeuristic(next_state), action)]

                    # Increase the level for the child
                    parent_tree_level = astar_tree.goto(astar_child_state)
                    if parent_tree_level:
                        astar_tree_level = parent_tree_level.treeLevel + 1
                    else:
                        astar_tree_level += 1

                    # create tree for the finding the data
                    astar_tree.elementName = next_state
                    astar_tree.elementParent = astar_child_state
                    astar_tree.elementScore = element_scored
                    astar_tree.elementPath.append(astar_child_state)
                    astar_tree.treeLevel = astar_tree_level
                    astar_object = astar_tree.add()

                    # If the state exists then add that to the queue
                    astar_queue.append(astar_object)

                else:
                    # Update the value leaf into the queue
                    astar_leaf_state = astar_tree.goto(astar_child_state)
                    astar_leaf_queue.append(astar_leaf_state)

Nesneye herhangi bir öğe ekleyebilir / nesneyi kaldırabilir, ancak yapıyı amaçlayabilirsiniz.


-4
def iterative_bfs(graph, start):
    '''iterative breadth first search from start'''
    bfs_tree = {start: {"parents":[], "children":[], "level":0}}
    q = [start]
    while q:
        current = q.pop(0)
        for v in graph[current]:
            if not v in bfs_tree:
                bfs_tree[v]={"parents":[current], "children":[], "level": bfs_tree[current]["level"] + 1}
                bfs_tree[current]["children"].append(v)
                q.append(v)
            else:
                if bfs_tree[v]["level"] > bfs_tree[current]["level"]:
                    bfs_tree[current]["children"].append(v)
                    bfs_tree[v]["parents"].append(current)

Bu soruya hiçbir şekilde okunabilir bir şekilde cevap vermiyor gibi görünmektedir.
AlBlue
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.