【问题标题】:Directed graph: checking for cycle in adjacency matrix有向图:检查邻接矩阵中的循环
【发布时间】:2015-12-24 11:16:32
【问题描述】:

关于 DFS 算法,有另一种方法来检查用邻接矩阵表示的有向图中是否存在环?

我找到了有关矩阵属性的零碎信息。 也许我可以将矩阵 A 与自身相乘 n 次,并检查每个结果矩阵中是否存在非零对角线。

虽然这种方法可能是正确的,但我如何才能显式提取表示循环的顶点列表? 那么这个假设算法的复杂度呢?

提前感谢您的帮助。

【问题讨论】:

  • 你的方法是对的,但似乎很难找到确切的顶点

标签: algorithm matrix graph


【解决方案1】:

假设在n 迭代之后,您有一个矩阵,其中i 行和j 列的单元格是M[n][i][j]

根据定义M[n][i][j] = sum over k (M[n - 1][i][k] * A[k][j])。假设M[13][5][5] > 0,意味着它有一个长度为13的循环,从5开始到5结束。要拥有M[13][5][5] > 0,必须有一些k,这样M[12][5][k] * A[k][5] > 0。假设k = 6,现在您知道循环中的另一个节点 (6)。随之而来的是M[12][5][6] > 0A[6][5] > 0

要拥有M[12][5][6] > 0,必须有一些k,这样M[11][5][k] * A[k][6] > 0。假设k = 9,现在,您知道循环中的另一个节点(9)。随之而来的是M[11][5][9] > 0A[9][6] > 0

然后,您可以重复执行相同的操作以查找循环中的其他节点。

【讨论】:

  • 你的方法看起来很有趣,谢谢!与 BFS 相比,该算法的复杂性如何?您认为它在计算成本方面可能更有效?
  • 我觉得这个答案很有见地;然而,该方法实际上是最短路径的Bellman-Ford 算法。它的运行时间比 DFS 差,但是它可以潜在地发现所有位于单次循环中的节点。算法的选择取决于目标;目标是找到所有位于循环上的节点还是找到任意循环(如果存在)?
  • @Codor 目标是列出所有循环,并且对于每个循环,列出位于循环上的所有节点。
【解决方案2】:

可以修改深度优先搜索来判断是否存在循环。算法第一次发现之前访问过的节点时,可以从堆栈中提取循环,因为之前找到的节点必须仍在堆栈中;使用用户定义的堆栈而不是调用堆栈是有意义的。复杂度将是O(|V|+|E|),对于未修改的深度优先搜索本身。

【讨论】:

  • 感谢您的回答。考虑到有关该算法的文献的广泛可用性,实现 DFS 可能更容易。
猜你喜欢
  • 1970-01-01
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多