【问题标题】:N-ary trees in numbanumba 中的 N 叉树
【发布时间】:2020-02-12 13:09:23
【问题描述】:

我需要实现一个树结构,其中每个节点都有任意数量的子节点。当孩子的数量已知时(链表、二叉树等),这似乎很简单,但我还没有设法在更一般的情况下实现它。

例如,我尝试通过将next 参数更改为列表来扩展此linked list example。但是,似乎没有deferred_type 的列表。关于如何实现这一点的任何想法?

from collections import OrderedDict 
from numba import njit, jitclass, types, int32, deferred_type, optional
import numpy as np 

node_type = deferred_type()

spec = OrderedDict() 
spec['data'] = int32 
spec['next'] = optional(types.ListType(node_type))


@jitclass(spec) 
class LinkedNode:
    def __init__(self, data, next):
        self.data = data
        self.next = next

    def prepend(self, data):
        return LinkedNode(data, self)


@njit def make_linked_node(data):
    return LinkedNode(data, None)


node_type.define(LinkedNode.class_type.instance_type)

【问题讨论】:

    标签: python numba


    【解决方案1】:

    我找到了一个替代方案,虽然不是我想要的,但仍然可以完成工作。它基本上是二叉树的标准扩展,在左右节点之间包含更多节点(参见this article)。

    这些结构通常只跟踪第一个(左)子节点,但我也有一个指向最后一个(右)子节点的指针,因为它有助于仅使用父节点来排列所有边。

    from collections import OrderedDict
    from numba import jitclass, int64, deferred_type, optional
    
    node_type = deferred_type()
    
    spec = OrderedDict()
    spec['id'] = int64
    spec['parent'] = optional(node_type)
    spec['left_child'] = optional(node_type)  # first child
    spec['right_child'] = optional(node_type) # last child
    spec['sibling'] = optional(node_type)  # next sibling
    
    
    @jitclass(spec)
    class Node:
        def __init__(self, id, parent):
            self.id = id
            self.parent = parent
            # initialize parent and left right children as None
            self.left_child = None
            self.right_child = None
            self.sibling = None
            if parent is not None:
                parent.add_child(self)
    
        @property
        def children(self):
        """ A list with all children. """
            children = []
            child = self.left_child
            while child is not None:
                children.append(child)
                child = child.sibling
            return children
    
        def add_sibling(self, sibling):
            self.sibling = sibling
    
        def add_child(self, child):
            # if parent has no children
            if self.left_child is None:
                # this node is it first child
                self.left_child = child
                self.right_child = child
            else:
                # the last (now right) child will have this node as sibling
                self.right_child.add_sibling(child)
                self.right_child = child
    
    
    node_type.define(Node.class_type.instance_type)
    

    【讨论】:

      猜你喜欢
      • 2010-09-16
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多