算法问题:在有向图中找到最长的基本周期

时间:2018-12-17 01:15:45

标签: algorithm graph np dfs

问题是:给定一个有向图,找到图中最长的简单循环。我已经搜索了问题,并找到了此链接Finding the longest cycle in a directed graph using DFS。答案解释了这是一个NP难题。

但是我对以下算法感到困惑,它似乎在O(| V | + | E |)时间中运行,因为我们只对每个边进行了一次访问。

保持以下变量:

(1)global max:图中最长循环的长度。
(2)Map<GraphNode, Integer> cache:存储从关键节点开始的最长周期的长度。
(3)Map<GraphNode, Integer> pathVisited:存储路径上已访问的节点和相应的步骤号。例如,A-> B-> C-> A,如果从A开始,地图将看起来像{A-> 1,B-> 2,C-> 3},并且再次输入A时,步骤变为4,因此周期长度为4-1 = 3
(4)Set<GraphNode> visited:包含已被充分研究的graphNode。

dfs(GraphNode cur, int curStep, Set<GraphNode> visited, Map<GraphNode, Integer> cache, Map<GraphNode, Integer> pathVisited):
    if visited.containsKey(cur), then 
        return // if the node have been explored, no need to explore again
    // if see a cycle, update the results(cache)
    if pathVisited.containsKey(cur), then 
       newCycleLen = curStep - pathVisited.get(cur)
       cache.put(cur, max {newCycleLen, cache.get(cur)})
       return 
    // no cycle yet, continue the search
    pathVisited.put(cur, curStep)
    for each neighbor of cur:
       dfs(neighbor, curStep + 1, cache, pathVisited)
    endfor
    visited.add(cur); // current node have been explored, in the future no need to visit it again.
    path.remove(cur)

我认为上述算法可以在O(| V | + | E |)时间内解决问题,因为在完全探查一个节点之后,我们将不再在该节点上开始dfs。

任何人都可以给我一些有关上述算法为何错误的提示吗?

2 个答案:

答案 0 :(得分:1)

请考虑以下图形:

     D -- A
   / |    |
  E  |    |
   \ |    |
     C -- B

现在,假设您在节点A上启动DFS,并按顺序B,C,D,E依次访问节点。除非我误解了您的代码在做什么,否则我不相信这访问顺序将使您能够找到最长的循环A,B,C,E,D,A,因为一旦访问了D,就将其分配给错误的深度,并切断返回A的路径。

答案 1 :(得分:0)

我认为问题是什么是“基本周期”。如果周期一次都访问了所有点,则DFS很好。但这是问题:

A---B
|\ /|
| E |
|/ \|
C---D

假设方向:

A-> B

B-> D,E

C-> D

D-> E,A

E-> C

DFS将发现最长周期为5,A-> B-> E-> C-> D-> A,但最长周期应为A-> B-> E-> C-> D-> E->一种。也许您应该尝试使用新视图