在networkx中生成并执行处理图

时间:2016-03-17 14:46:09

标签: python graph networkx dataflow

我有许多'流程',每个流程都作为一个类实现(实现一个接口 - dataset)和一些'数据集',再次由一个类 - root / \ dataset1a dataset1b | | dataset2 dataset2b / | \ / \ dset3a | dset3b dset4a dset4b \ | / \ | / \ | / dataset3a4a 表示。

可以创建数据集及其依赖的有向非循环图。它可能看起来像:

process

要访问每个数据集,必须应用一个进程(由DiGraph类表示)。目前我正在使用网络x创建X,其中每个数据集对象都是一个节点,到达process节点的进程是指向ROOT对象的节点上的属性。 dataset1a只是一个提供起始节点的虚拟节点。

这是用networkx表示图形的好方法吗? 鉴于存在dataset1bprocess并且必须创建它们的后代(其中每个先前的数据集都是dataset3a4a类的输入)...什么是遍历图形的好方法的是:

  • 直到访问了所有'依赖项(并创建了数据集)后才访问节点
  • 可以找到依赖的“节点”......例如。如果我在dset3a节点,我必须能够发现创建该数据集的所有“输入” - dset4adataset2conda update conda conda update anaconda

1 个答案:

答案 0 :(得分:0)

Python提供了一些内省工具,您可以使用它们代替networkx。 ArrayList<Coins> coins = purse1.getCoins(); for(Coin coin: coins){ System.out.println(coin.toString); } 方法返回给定类的直接子类的列表:

__subclasses__

In [36]: Root.__subclasses__() Out[38]: [__main__.DataSet1a, __main__.DataSet1b] In [61]: DataSet2.__subclasses__() Out[61]: [__main__.DSet3a, __main__.DSet3b, __main__.DataSet3a4a] In [62]: DataSet3a4a.__subclasses__() Out[62]: [] 属性返回类的基础(直接父类):

__bases__

In [63]: DataSet3a4a.__bases__ Out[63]: (__main__.DSet3a, __main__.DataSet2, __main__.DSet4a) 属性为您的第二个问题提供了答案 如何找到创建数据集的输入。

要回答第一个问题,您可以使用__bases____subclasses__ 建立自己的遍历功能:

__bases__

产量

import collections
class Root(object): pass
class DataSet1a(Root): pass
class DataSet1b(Root): pass
class DataSet2(DataSet1a): pass
class DataSet2b(DataSet1b): pass
class DSet3a(DataSet2): pass
class DSet3b(DataSet2): pass
class DSet4a(DataSet2b): pass
class DSet4b(DataSet2b): pass
class DataSet3a4a(DSet3a, DataSet2, DSet4a): pass

def visit(cls):
    seen = set([cls])
    queue = collections.deque(cls.__subclasses__())
    while queue:
        subcls = queue.popleft()
        if subcls in seen: continue
        # check that all its bases have been seen
        for base in subcls.__bases__:
            if base not in seen:
                # if a base has not been seen, push subcls to the back of the queue
                queue.append(subcls)
                break
        else:
            # all the bases of subcls have already been seen
            seen.add(subcls)
            yield subcls
        # add all the subclasses of subcls to the queue
        queue.extend(subcls.__subclasses__())

for cls in visit(Root):
    print(cls.__name__)