标签:复杂 产生 深度优先 top 统计 过程 sed 信息 统计信息
有向图G(V,E),圈是一个起始节点与终止节点相同的路径,即 a->….->a。找到所有的圈可能要遍历所有的路径,这就涉及到算法性能的考虑。本文基于深度优先搜索,讨论查找所有圈的算法加速策略。
深度优先搜索算法是从已知节点出发,图的一种遍历算法。只要一个节点被同源两个路径访问,这两个路径则形成一个圈。因为每个节点只处理一次,所以时间与空间复杂度都是O(N)。其算法如下:
DFS(a) for undirected graph
stack.push(a)
while not stack.empty
i = stack.pop
mark i as accessed
{j} = adjacent(i)
stack.push({j where j is not accessed })
对于无向图来说,每个 i的邻节点 j ,如果已经 accessed,那么形成一个圈。注意此时并不知道圈中的每个节点是什么。因此算法要针对有向图改造,而且要记录圈中的每个节点,每个圈都不能遗漏,还要保持高性能。
对于有向图来说,要记录从 a 到 i 的路径,才能判断 i的邻接点j 是否形成一个圈。算法如下:
DFS(a) for directed graph
stack.push(<{a}, 0>) //采用 stack 记录路径
while not stack.empty
<set, k> = stack.top
mark set[k++] not in stack // in-stack为路径标记
if set[k] in stack
record(set[k], stack) //在stack中找到圈上所有节点
continue
mark set[k] in stack // set[k]为当前路径上的节点
if k>|set|
stack.pop
else
stack.push(<adjacent(set[k]), 0>)
这个算法遍历了所有从 a 出发的路径,满足了查找圈的功能,不会遗漏任何一个圈。然而要穷举所有路径,这个算法通常会很慢,需要采用一些加速策略。
通常的策略是对图的简化,各种情况如下:
另一个策略是一边查找,一边合并在一个圈上的节点。节点在一个圈上,这是一个等价关系。合并节点可以提高圈套圈情况下的查找性能;还可以混合使用各种查圈算法。例如,无向图的查圈算法速度不错,但是会遗漏一些圈,因此可以放在有向图的查圈算法之前执行。
还有一种策略是对图建立一系列简化图,即建立简化映射,然后对简化图进行查圈操作。当查圈操作和其它应用操作需要混合处理时,这种策略的算法更清晰。
开发加速策略,需要注意两点:
这个问题没有查到更好的解决方案,主要采用图简化策略来加速算法,结果还不错。
标签:复杂 产生 深度优先 top 统计 过程 sed 信息 统计信息
原文地址:http://www.cnblogs.com/liuyunfeng/p/6121465.html