如何确定删除给定循环是不是会断开图表
Posted
技术标签:
【中文标题】如何确定删除给定循环是不是会断开图表【英文标题】:How to determine whether removing a given cycle will disconnect a graph如何确定删除给定循环是否会断开图表 【发布时间】:2016-01-07 07:24:46 【问题描述】:我已经看到了检测图表中循环的方法,但我仍然没有设法找到检测“桥式”循环的方法。所以假设我们在一个连通(和无向)图中找到了一个循环。我们如何确定删除此循环是否会断开图形?去除循环,我的意思是去除循环中的边(所以顶点不受影响)。
一种方法是清楚地计算移除前后的组件数量。我只是想知道是否有更好的方法。
如果碰巧有一个既定的算法,谁能指点我相关的工作/论文/出版物?
【问题讨论】:
Articulation Point
在图表中会有所帮助。
参考this
你是删除循环顶点还是只删除边?
@DavidEisenstat 我只删除边缘。
@paulpaul1076 实际上我需要的是:假设我们在图中找到了一个循环,我们如何检查删除它是否会断开图? (我之前可能以不好的方式表达了我的问题 - 对此感到抱歉。我已经编辑了我的帖子以使其更清楚。)正如你提到的,一种方法是计算组件的数量。但我只是想知道是否有更好的方法。我之前看过你关于关节点的帖子,我认为这看起来很有趣。
【参考方案1】:
这是简单的算法,复杂性方面我认为没有更有效的方法来进行检查。
从您的边列表开始 (cycleEdges) 获取 cycleEdges 内的顶点集 (cycleVertices) 如果 cycleVertices 中的顶点仅包含属于 cycleEdges 一部分的边,则返回 FALSE 对于 cycleVertices 中的每个顶点 递归地跟随不在 cycleEdges 中的顶点边缘(避免已经访问过的顶点) 如果到达的顶点不在 cycleVertices 中,请将其添加到集合 outsideVertices(停止递归搜索此路径) 如果仅到达 cycleVertices 中的顶点,则返回 FALSE 如果 outsideVertices 包含 1 个元素返回 TRUE 在 outsideVertices 中选择一个顶点并将其从 outsideVertices 中删除 递归地跟随不在 cycleEdges 中的顶点的边(避免已经访问过的顶点)(倾向于选择包含 outsideVertices 中的顶点的边,以提高大型图的运行时间) 如果到达 outsideVertices 中的顶点,则将其从 outsideVertices 中删除 如果 outsideVertices 为空,则返回 TRUE 返回 FALSE【讨论】:
那么,cycleEdges是所有循环的边还是一个循环? @paulpaul1076 - cycleEdges 表示我们正在测试的当前循环中的边缘。 OP 希望采用已经找到的循环,看看是否可以将其删除,同时仍保留图形的连接性。【参考方案2】:你可以为 E+V 做到这一点。 您可以通过 dfs + 动态编程获得 E+V 图中的所有桥梁。
http://www.geeksforgeeks.org/bridge-in-a-graph
保存它们(只需将 boolean[E] 设为 true。 然后你可以说 O(1) 的边缘是否是桥。 您可以从您的循环中获取所有边缘并验证它是否是桥。
【讨论】:
【参考方案3】:Vish 提到的关节点绝对是正确的方向。不过可以说更多。关节点可以通过修改后的 DFS 算法找到,如下所示:
执行 DFS,为每个数字分配其 DFS 编号(例如,在它之前访问的节点数)。当您遇到已经发现的顶点时,将其 DFS 编号与当前顶点进行比较,您可以存储与该顶点关联的 LOW 编号(例如,该节点“看到”的最低 DFS 编号)。当您递归回到起始顶点时,您可以将父顶点与子顶点的 LOW 数进行比较。当您递归时,如果父顶点曾经看到大于或等于其自己的 DFS 数的子节点的小数,则该父顶点是一个关节点。
我在这里经常使用“子”和“父”作为描述符,因为在 DFS 树中,我们必须考虑根的特殊情况。如果它看到一个子节点的小数大于或等于它自己的 DFS 数,并且它在树中有两个子节点,那么第一个顶点就是一个关节。
Here's a useful art. point image
另一个需要熟悉的概念,尤其是对于无向图,是双连通分量,也就是顶点与所有其他顶点处于循环中的任何子图。
Here's a useful colored image with biconnected components
你可以证明任意两个双连通分量只能共享一个顶点最大值;两个“共享”顶点意味着这两个顶点以及组件中的所有其他顶点都处于一个循环中,因此这两个组件实际上是一个大组件。正如您在图中看到的,由两个组件(具有不止一种颜色)共享的任何顶点都是一个关节点。删除包含任何关节点的循环将因此断开图形。
【讨论】:
我找不到修改后的 DFS 算法的原始论文,但是在图中找到关节点有很多文档。【参考方案4】:好吧,因为在一个循环中,任何顶点x都可以到达任何其他顶点y,反之亦然,那么它是一个强连通分量,所以我们可以收缩一个循环变成一个表示循环的顶点。可以使用 DFS 对 O(n+m) 执行该操作。现在,我们可以再次应用 DFS 来检查收缩的循环是否是关节顶点,如果是,则删除它们将断开图,否则不是。总时间为 2(n+m) = O(n+m)
【讨论】:
以上是关于如何确定删除给定循环是不是会断开图表的主要内容,如果未能解决你的问题,请参考以下文章
如何确定给定时区中的给定时间是不是在postgresql中是DST?