【问题标题】:cycle detection undirected graph with unused edges具有未使用边的循环检测无向图
【发布时间】:2019-12-12 11:52:15
【问题描述】:

我有一个带边的无向图。每条边都有一定的属性,比如点 A 和点 B 之间的边之一是

{
travelTime :10hours
travelPath : air
}

C点和D点之间的另一个可能是

{
travelTime :1hours
travelPath : Metro
} 

我们得到了这样一个图表和已知的 travelPaths

 {air, Metro,Rail, Bus ,Auto,Rickshaw  }

提供给我们的一组边说 unUsedEdges 不属于固定图的一部分。它们也具有上述性质,只是它们不属于固定图。现在在这个固定图中添加了一条来自 unUsedEdges 的边。我们必须说明是否存在一个只有 Metro 和 Rail 类型的循环,其中包括这个新引入的边缘。 然后删除新引入的边缘,我们检查来自 unUsedEdges 的另一个边缘。如果有一个循环,我们需要循环边缘。我们需要来自所有 unUsedEdges 边的所有循环。

固定图很大。 unUsedEdges 集也很大。我们可以使用 DFS 在 O(V+E) 时间内检测无向图中的循环。对所有 unUsedEdges 重复执行此操作需要时间。

有更快的方法吗?

【问题讨论】:

  • 一个想法可能是在 O(V^3) 中(预)计算固定图(w.r.t. {Metro, Rail})的reachability matrix。之后,您可以通过检查边是否连接两个可到达的顶点来检查 O(1) 中的每个 unUsedEdge。

标签: algorithm graph-algorithm undirected-graph


【解决方案1】:

由于您想检测仅地铁或仅铁路边缘的循环,我们可以通过先仅使用地铁边缘然后仅使用铁路边缘运行算法来简化问题。因此,在没有不同边缘类别的情况下工作的算法可以很容易地适应整个问题。

使用disjoint-set data structure 的变体可以解决简化的问题。我们可以将固定边插入数据结构中,然后查询(不插入)每条新边。这告诉我们是否存在循环,但如果我们想恢复循环,我们需要扩充数据结构。

在数据结构中维护两个父指针数组:一个正常用于使用路径压缩的不相交联合数据结构,另一个没有路径压缩。没有路径压缩的必须保持父指针树中的每个(有向)边都是原始图的(无向)边的不变属性;这意味着有时需要翻转边的方向以便为联合操作重新扎根树。

在测试一条非固定边时,我们使用路径压缩数组来查询是否存在循环,如果存在,我们通过跟随另一个数组中的两个顶点到它们在父数组中的lowest common ancestor来恢复它。指针树。这是有效的,因为未压缩数组中的所有边都是来自原始固定图的边,并且可以从该边以及从其每个顶点到共同祖先的两条路径形成一个包括未固定边的循环。

整体运行时间为 O(m α(v) + v² + nv) in最坏情况,其中v是顶点数,m是固定边数,n是非固定边数,而 α 是增长非常缓慢的inverse Ackermann function

  • m α(v) 项是 O(m) 在联合上“查找”查询的成本 -找到数据结构。执行了另一个 O(n) 次“查找”查询,但这些查询的术语由 nv 主导。

  • v² 项是在未压缩数组中重新生根树最多 O(v) 次,翻转最多 O(v) 在最坏的情况下每次都有边。

  • nv 项是最坏情况下的输出大小;最多可以有 n 个循环,每个循环的长度最多为 v。如果大多数不固定边不创建循环,和/或循环通常相对于 v 短,那么运行时间会明显更快。算法在这个意义上是output-sensitive

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 2016-03-28
    相关资源
    最近更新 更多