我创建了一个轻量级图形库,它有 3 个对象(顶点、边缘、图形)和 1 个函数(topo_sort),如下所示:
class DAGError(Exception): pass
def topo_sort(graph):
sorted_list = []
def visit(vertex):
nonlocal sorted_list
if vertex.idle:
raise DAGError('Graph has at least one cycle.')
if not vertex.done:
vertex.idle = True
for neighbor in vertex.vertices():
visit(neighbor)
vertex.done = True
vertex.idle = False
sorted_list.insert(0, vertex)
queue = [vertex for vertex in graph.vertices() if not vertex.done]
while queue:
visit(queue.pop(0))
return iter(sorted_list)
如果我有一个扁平的 DAG,这可以正常工作。但我想要实现的是在我的主图中添加子图(或嵌套图),正如你在我绘制的插图中看到的那样:
这仍然是一个 DAG,所以如果我对此运行我的函数,正常 topo_sort
输出将是这样的:
V0, V3, V1, V5, V4, V8, V7, V12, V11, V13, V14, V2, V6, V10, V9, V15, V17, V16
然而,我的首选输出是当子图所依赖的所有顶点在处理子图的顶点之前“处理”时 - 所以它应该是这样的:
V0, V1, V8, # vertices of maingraph
V3, V5, V4, V12 # vertices of subgraph_0
V7, V11, V13, # vertices of subgraph_1
V14 # vertex of subgraph_0
V2 # vertex of maingraph
V6, V10, V9, V15 # vertices of subgraph_2
V16, V17 # vertices of maingraph
但我找不到任何资源:
- 如何将图中的顶点“标记”或“存储”为子图的一部分?
- 如何根据顶点的子图依赖关系对顶点进行排序(如上面的示例)?
- 如何将子图作为独立图获取或处理?
我希望我能足够详细地解释我的问题——尽管如果有什么遗漏,请告诉我,我会用遗漏的部分来扩展我的问题。
提前致谢!
编辑:
我发现了这个(Boost Graph Library,BGL),它看起来解决了我遇到的一个非常相似(或完全相同?)的问题,虽然我不熟悉 C++,所以我不明白它是怎么回事工作以及它到底在做什么——但我把它放在这里,也许有人会发现回答我的问题很有帮助..
编辑2:
我也接受伪代码,而不仅仅是 python!当然,如果现有的 python 库知道这一点,我对此很感兴趣,但是,我不想使用如此庞大的库graph-tools
,例如——这就是我创建自己的库的原因,所以我更喜欢实现而不是库。