根据输入/输出对节点排序

时间:2015-05-06 06:11:31

标签: python nodes

我有一个节点系统,每个节点只存储其输入和输出,但不存储其索引。这是一个简化的例子:

class Node1:
    requiredInputs = []

class Node2:
    requiredInputs = ["Node1"]

class Node3:
    requiredInputs = ["Node2"]

class Node4:
    requiredInputs = ["Node3", "Node2"]

现在我想订购那些节点,以便在处理该节点时已经处理了所有输入。对于这个简单的例子,可能的顺序是[Node1,Node2,Node3,Node4]。

我的第一个想法是使用蛮力检查每种可能的组合。但是,对于更多的节点,这将非常慢。

什么是更有效的方法呢?我不需要实现,只需要一个基本的想法或算法。

2 个答案:

答案 0 :(得分:2)

你想要的是拓扑排序节点。

http://en.wikipedia.org/wiki/Topological_sorting

最基本的想法是为每个节点分配一个整数,该节点的开头等于它的输出数量。然后将值为0的所有节点(即没有输出的节点)添加到将表示订单的列表中。对于每个附加到列表的节点,从与该节点输入的节点关联的值中减去一个节点。如果这些节点中的任何节点现在具有零值,则也将它们添加到列表中。重复这样做。保证最终进程终止,只要您没有循环,并且列表中的节点将以输出始终在输出之前的方式进行排序。

答案 1 :(得分:2)

算法

拓扑排序确实是要走的路;根据您的要求,我不会编写完整的实现。

大纲&笔记

类型

首先,您将requiredInputs代码存储为类,而不是字符串。这将使比较方式更加优雅:

class Node1:
    requiredInputs = []

class Node2:
    requiredInputs = [Node1]

class Node3:
    requiredInputs = [Node2]

class Node4:
    requiredInputs = [Node3, Node2]

输入和输出数据结构

然后,您可以将节点放在两个数组中,用于输入和输出。这可以就地完成(使用单个阵列),但它很少值得麻烦。

unordered_nodes = [Node4, Node3, Node2, Node1]
ordered_nodes = []

这是算法大纲:

while there are unordered_nodes:
    for each node N in unordered_nodes:
        if the requiredInputs of N are already in ordered_nodes:
            add N to ordered_nodes
            remove N from unordered_nodes
            break

预期结果

实施后,应该给出:

print ordered_nodes
[<class __main__.Node1 at 0x10a7a8bb0>, 
 <class __main__.Node2 at 0x10a7a83f8>, 
 <class __main__.Node3 at 0x10a7a80b8>, 
 <class __main__.Node4 at 0x10a7a8600>]

优化

有很多方法可以优化或改进拓扑排序。和以前一样,我在没有透露任何实施的情况下暗示了一些。

  • 按某些属性对输入数组进行预排序
  • 使用单个阵列就地排序
  • 使用不同的数据结构来表示节点之间的关系
  • 在任何迭代中向ordered_nodes添加多个节点