在有向图中查找每个顶点的可到达顶点

时间:2015-04-25 23:00:37

标签: algorithm complexity-theory theory graph-theory

我知道执行此操作的强力方法是对图的所有顶点执行DFS。因此,对于此算法,复杂度将为O(V | V + E |)。但有更有效的方法吗?

3 个答案:

答案 0 :(得分:3)

我真的怀疑通用图没有更好的算法。我在主题[1] [2]上找到的所有论文都描述了在O(| V | * | E |)时间内运行的算法。在最坏的情况下,这并不比你天真的尝试好。

甚至维基百科页面[3]都说最快的算法可以将问题减少到矩阵乘法,最快的算法只比基线稍微好一点。

[1] http://ion.uwinnipeg.ca/~ychen2/conferencePapers/tranRelationCopy.pdf

[2] http://www.vldb.org/conf/1988/P382.PDF

[3] http://en.wikipedia.org/wiki/Transitive_closure#Algorithms

答案 1 :(得分:3)

我从http://research.microsoft.com/pubs/144985/todsfinal.pdf等论文中得到的结论是,在一般情况下,没有比O(VE)O(V^3)更好的算法。对于稀疏图和其他特殊图,有更快的算法。但是,似乎你仍然可以通过分离"索引构建"来自" query",如果您对将对数据进行的查询数量有所了解。如果要进行大量查询,如果所有数据都已预先计算(DFS或Floyd-Warshall等)并存储在O(1)空间中,则O(n^2)可用于查询。另一方面,如果查询相对较少,则可以以查询时间为代价减少空间和/或索引构建时间。

答案 2 :(得分:1)

[编辑:正如kraskevich所指出的,最后的查询步骤可能比我原先声称的更糟糕:即使输出大小为O(| V |),也最多为O(| V | ^ 2) ,这并不比没有任何预处理的普通DFS好。]

在最坏的情况下,需要O(| V | ^ 2)空间来显式存储所有这些信息 - 即,存储每个顶点的可到达顶点的完整列表(想想每个顶点的图形)每个其他顶点都有一条边。但是有可能以这样的方式表示它,只需要O(| V |)空间,并且这种表示可以在O(| V | + | E |)时间内构建,并且对它的查询将是只花时间与答案的大小成比例(可达顶点的数量)

基本思想是: strongly connected component(SCC)中的每个顶点都可以到达同一SCC中的每个其他顶点(这是SCC的定义),并且可以到达SCC中的所有顶点可以到达,没有其他顶点。

  1. 查找所有SCC;这可以在O(| V | + | E |)时间内完成。构建表SCC,如果u的SCC是i,则SCC(u)= i(G和SCC中的两个顶点都可以表示为整数)。然后再通过这个表来构建一个双表Verts,这样Verts(i)包含了第i个SCC中所有顶点的列表。
  2. 构建一个新的图G',其顶点是G的SC。G'必然是非循环的。
  3. 因此,给定G中的顶点u,查找其SCC,SCC(u)。叫这个我。从顶点i开始执行DFS到G':对于在此DFS期间遇到的每个顶点(G')j,输出Verts(j)中的每个顶点(G)。