在图表中隔​​离 "braided sections"

Isolating "braided sections" in a graph

假设我有一个图形表示如下:

如你所见,有一个"braided section",其中可以走许多不同的路径,但是,如果你继续前进(至少沿着主轴的一个方向),你总是会结束在 "braid".

末尾的同一点向上

此图可以在任一方向延伸很长的距离,并且沿途有多个任意复杂度的辫子。

是否有某种算法能够隔离蓝色圆圈节点,表示 "braid" 的开始和结束?或者更进一步,只是 return 包含辫子的子图,在这些节点处剪断?

我在 Google 中无法阐明这个问题,我的图形库的文档没有解释它实现的各种算法。

我目前正在使用 Python NetworkX,但如果算法没有直接实现,我不反对手动实现它。

我还应该指定图形最好是有向的,这样所有边都指向主轴的一个方向,但是也可以使用有向图的解决方案会更好。

编辑:这是我根据@kaya3 的回答实现的:

articulation_points = nx.articulation_points(graph)
for node in articulation_points:
    if nx.degree(graph, node) > 2:
        print(node)

我不知道执行此操作的特定算法,但实现一个很容易。您以广度优先的方式遍历您的节点,并跟踪您正在探索的分支数量。当数字增加到 1 以上时,您就处于 "braid" 的开头。当您同时探索的分支数量下降到 1 时,您就找到了辫子的末端。这可能不是最佳的,因为您的复杂性大于 O(n),因为如果您在各个分支中有不同数量的节点,则不能跳过已经访问过的节点(如果这样做,您可能会跳过辫子的末端) ,但除非你要处理数百万个节点、高分支因子和大的不平衡,否则我希望你应该没问题。

您也可以尝试使用介数中心性,因为它可以很好地衡量通过节点的最短路径的数量。启动分支或关闭分支的节点应该比其他节点具有更高的介数中心性。这当然不准确,因为辫子内部的复杂行为可能导致其中的某些节点也具有很高的介数中心性,但我认为这是一种快速的方法(因为它已经实现,如果你有,该功能可能需要很长时间很多节点)可能会产生您期望的结果。

这个问题可以通过深度优先搜索的形式找到 articulation points (a.k.a. cut-vertices) of the graph; these are the vertices which, if you deleted them from the graph, then the graph would become disconnected. The set of all articulation points can be found in linear time 来解决。

很明显,关节点要么是辫子的起点或终点,要么是一根辫子的末端和另一根辫子的起点之间路径上的点。因此辫子的起点和终点分别是出度或入度大于 1 的关节点。 (如果图形是无向的,那么你想要度数大于2的关节点。)

如果辫子立即从第一个顶点开始,或在最后一个顶点结束,这是一种特殊情况。在那种情况下,它不是一个清晰点,但你确实想计算它。因此,如果其(出)度大于 1,则应包括第一个点,如果其(入)度大于 1,则应包括最后一个点。