使用DFS在有向图中查找最长周期

时间:2010-12-25 11:18:18

标签: algorithm graph-theory depth-first-search

我需要使用DFS在有向图中找到最长的周期。

我曾经看到这篇维基百科的文章描述了这样做的方式,我认为它解决了这个问题,例如用以下三种状态之一标记节点:节点尚未访问,完成搜索节点,节点访问,但不是尚未完成访问。

如果有人能与我分享链接,我将不胜感激。顺便说一句,它不是Tarjan的算法。

以下问题是我想解决的问题,如果你想知道的话。

第一行给出的两位数字是N和M,每个数字代表节点数和有向边数。

从第二行给出M组两个数字A和B,这意味着节点A和B已连接但您只能遍历从A到B的节点。

input.txt中:

7 9  
1 2  
2 3  
3 1  
3 4  
4 5  
5 1  
5 6  
6 7  
7 2  

在这种情况下的答案是6,因为2> 3> 4> 5> 6> 7> 2。

4 个答案:

答案 0 :(得分:8)

我认为最长的基本周期(或电路)是比最长周期更好的术语。

无论如何,这个pdf可能会有所帮助:Finding All the Elementary Circuits of a Directed Graph

这个有一年历史的stackoverflow问题还有很多相关问题和算法的链接:  Finding all cycles in a directed graph

答案 1 :(得分:2)

确实可以证明,你可以在多项式时间内将哈密顿循环减少到这个问题,因此它最终得到NP完全。无论图表是指向还是未指向。

就算法而言,解决问题的简单方法是回溯---从节点i = 1到n开始,并始终探索从特定节点i开始的所有周期。完成此操作后,您将从节点i + 1开始消除节点i并继续执行图表的其余部分。您可能希望在DFS中执行类似节点着色的操作,以区分您再也不想访问的节点以及您在此特定传递中沿路径访问的节点。您可能还希望在节点上添加类似于发现时间的时间戳,但在这种情况下,每次发现节点时都需要编写这些时间,因为大多数节点将被多次发现。上面列出的论文可能会有所帮助,还有更多方法可以做到这一点。

答案 2 :(得分:0)

这个问题是NP-Complete,并且没有多项式时间算法。 你问题的大小是多少?我的意思是输入图表中会有多少节点

最长周期问题减少到哈密顿循环问题: http://mathworld.wolfram.com/HamiltonianCycle.html

答案 3 :(得分:0)

我有一个答案,解释了在另一篇文章中使用Python和networkX在有向图中查找所有循环的简单方法。 Finding all cycles in a directed graph

解决方案将输出一个包含有向图的所有周期的列表。

您可以使用此输出查找最长的循环,如下所示:

import networkx as nx

# Create Directed Graph
G=nx.DiGraph()

# Add a list of nodes:
G.add_nodes_from(["1","2","3","4","5","6","7","9"])

# Add a list of edges:
G.add_edges_from([("7","9"),("1","2"),("2","3"),("3","1"),("3","4"),("4","5"),("5","1"),("5","6"),("6","7"),("7","2")])

#Return a list of cycles described as a list o nodes
all_cycles = list(nx.simple_cycles(G))

#Find longest cycle
answer = []
longest_cycle_len = 0
for cycle in all_cycles:
    cycle_len = len(cycle)
    if cycle_len>longest_cycle_len:
        answer =cycle
        longest_cycle_len = cycle_len

print "Longest Cycle is {} with length {}.".format(answer,longest_cycle_len)

答案:最长周期为[' 3',' 4',' 5',' 6&#39 ;,' 7',' 2'],长度为6。

如果你发现有趣的话也会提升原来的答案。这是一个有很多答案的旧讨论,它将有助于推出新的解决方案。