如何在没有邻接矩阵的情况下有效地在图中找到连接的组件?

时间:2019-04-18 21:48:41

标签: algorithm graph time-complexity connected-components

我想在无向图中找到连接的组件。但是,我没有邻接矩阵。相反,我有一组顶点以及一个告诉我两个顶点是否相邻的函数。查找所有已连接组件的最有效方法是什么?

我知道我可以只计算整个邻接矩阵并使用深度优先搜索来找到所有组件。但这不是很有效,因为我需要检查每对顶点。

我当前正在执行以下步骤:

  1. 选择任何未分配的顶点,该顶点现在已是其自身的组成部分
  2. 找到该顶点的所有邻居并将其添加到组件中
  3. 找到刚添加的顶点的所有邻居(在尚未分配给任何组件的那些顶点中)并添加它们
  4. 重复上一步,直到找不到新邻居
  5. 组件现已完成,从第一步开始重复查找其他组件,直到分配了所有顶点为止

这是伪代码:

connected_components(vertices):
  // vertices belonging to the current component and whose neighbors have not yet been added
  vertices_to_check= [vertices.pop()]
  // vertices belonging to the current component
  current_component = []
  components = []
  while (vertices.notEmpty() or vertices_to_check.notEmpty()):
    if (vertices_to_check.isEmpty()): // All vertices in the current component have been found
      components.add(current_component)
      current_component = []
      vertices_to_check= [vertices.pop()]
    next_vertex = vertices_to_check.pop()
    current_component.add(next_vertex)
    for vertex in vertices: // Find all neighbors of next_vertex
      if (vertices_adjacent(vertex, next_vertex)):
        vertices.remove(vertex)
        vertices_to_check.add(vertex)
  components.add(current_component)
  return components

我知道,在大多数情况下,此方法比计算邻接矩阵要快,因为如果已知两个顶点属于同一分量,则不需要检查两个顶点是否相邻。但是有办法改进这种算法吗?

1 个答案:

答案 0 :(得分:2)

最终,任何算法都必须为原来属于单独组件的每对顶点调用vertices_adjacent,因为否则它将无法验证这些组件之间没有链接。

现在,如果大多数顶点都属于单个分量,则可能不会有太多这样的对;但是除非您期望大多数顶点都属于单个分量,否则没有专门针对这种情况进行优化的意义。因此,放弃这种情况,最好的情况是:

  • 结果恰好是两个分量,每个分量具有相同数量的顶点(每个½| V |)。因此,有¼| V | 2 对顶点属于不同的分量,因此您需要为每个对调用vertices_adjacent
  • 这两个组成部分很完整,或者您很幸运地选择了要检查的边缘,因此您可以通过仅检查| V 来检测连接的零件。 | − 2对。

。 。 。这仍然涉及使¼| V | 2 + || V | − 2次调用vertices_adjacent。相比之下,构建邻接表方法使½| V | 2 -½| V |调用-比最佳情况要大,但要小于2。(最糟糕的情况仅相当于“建立邻接表”方法。)如果没有一个分量包含两个以上的顶点,或者该图是非循环的,并且您不太可能选择要首先检查的边,则将发生这种情况。大多数图将位于两者之间。)

因此,对于精确调用vertices_adjacent的最小次数精确而言,可能不值得进行过于紧密的优化。

也就是说,您的方法对我来说似乎很合理;它不会对vertices_adjacent进行任何不必要的调用,因此,如果可以更好地猜测哪些调用对消除以后的调用很有用,那么唯一的改进就是提高概率。 / p>

一种可能性:根据power-law distribution,在许多图中,有些顶点有很多邻居,而有些顶点却很少。因此,如果根据已知的顶点数确定顶点的优先级,则可以利用该模式。 (我认为,如果大多数顶点确实确实都属于单个分量,那么这特别有用,这是唯一的优于2的改进甚至是可以想象。)但是,您必须测试一下,看看它是否真的对您感兴趣的图表有所影响。