检测有向图内所有周期的最有效算法是什么?
我有一个有向图,表示需要执行的作业计划,其中作业是节点,而依赖项是边缘。 我需要检测此图中导致循环依赖性的循环的错误情况。
#1楼
我已经在sml(命令式编程)中实现了这个问题。 这是大纲。 查找入度或出度为0的所有节点。 这样的节点不能成为循环的一部分(因此请删除它们)。 接下来,从此类节点中删除所有传入或传出边缘。 将这个过程递归地应用于结果图。 如果最后没有剩下任何节点或边,则该图没有任何循环,否则就没有。
#2楼
https://mathoverflow.net/questions/16393/finding-a-cycle-of-fixed-length我最喜欢这种解决方案,特别适合4种长度:)
此外,phys向导还说您必须执行O(V ^ 2)。 我相信我们只需要O(V)/ O(V + E)。 如果该图已连接,则DFS将访问所有节点。 如果该图具有连接的子图,则每次我们在该子图的顶点上运行DFS时,我们都将找到连接的顶点,并且在下次运行DFS时不必考虑这些顶点。 因此,为每个顶点运行的可能性是不正确的。
#3楼
没有一种算法可以在多项式时间内找到有向图中的所有循环。 假设有向图有n个节点,并且每对节点之间都有相互连接,这意味着您有一个完整的图。 因此,这n个节点的任何非空子集都表示一个周期,并且此类子集的数量为2 ^ n-1。 因此,不存在多项式时间算法。 因此,假设您有一个有效的(非愚蠢的)算法,该算法可以告诉您图中的有向循环数,则可以先找到强连接的组件,然后将算法应用于这些连接的组件。 由于循环仅存在于组件内部,而不存在于组件之间。
#4楼
如果DFS找到指向已访问顶点的边,则在那里存在一个循环。
#5楼
Tarjan的强连接组件算法具有O(|E| + |V|)
时间复杂度。
有关其他算法,请参阅Wikipedia上的牢固连接组件 。
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3167136