【问题标题】:Isolating "braided sections" in a graph在图中隔离“编织部分”
【发布时间】:2020-05-23 08:48:09
【问题描述】:

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

如您所见,有一个“编织部分”,其中可以采取许多不同的路径,但是,如果您继续前进(至少沿着主轴的一个方向),您总是会到达“辫子”末端的同一点。

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

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

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

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

我还应该指出,理想情况下,该图可以是定向的,使得所有边都指向主轴的一个方向,但是也可以使用有向图的解决方案会更好。

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

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

【问题讨论】:

    标签: python networkx graph-theory topology


    【解决方案1】:

    这个问题可以通过找到图的articulation points(又名切割顶点)来解决;这些是顶点,如果您将它们从图中删除,则图将断开连接。通过深度优先搜索的形式得到所有关节点can be found in linear time的集合。

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

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

    【讨论】:

    • 我在上一个答案上跳了起来,这个更简洁,并且也涵盖了整个图中有很多伪节点的情况。
    • 实际上,这个解决方案还有一个警告,我的要求不够具体——我实际上想找到编织的间隔。虽然这确实让我得到了间隔开始和停止的点,但我不确定区分沿着图表在编织内部或外部的位置,特别是当存在许多伪节点时,就像在示例中一样。
    • 我明白了。一种解决方案是删除不是辫子开始或结束的关节点,然后找到连接的组件。这也是线性时间。
    【解决方案2】:

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

    【讨论】:

    • 完美,如此简单而优雅的解决方案让我望而却步。它也适用于无向图。
    • 在无向图上它有一个问题,因为当你到达两个分支相遇的“辫子”的末端,但两个分支没有同时到达末端时,它会开始向后探索另一个分支。这与向前两个方向的分支没有区别。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-13
      • 2014-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多