[英]Algorithm Problem: Find the longest elementary cycle in a directed graph
問題是:給定一個有向圖,找出圖中最長的簡單循環。 我搜索了這個問題,找到了這個鏈接使用 DFS 在有向圖中找到最長的周期。 答案說明這是一個 NP 難題。
但是我對以下算法感到困惑,它似乎在 O(|V| + |E|) 時間內運行,因為我們只訪問了每條邊一次。
維護以下變量:
(1) global max
:圖中最長循環的長度。
(2) Map<GraphNode, Integer> cache
:存儲從關鍵節點開始的最長循環的長度。
(3) Map<GraphNode, Integer> pathVisited
:存儲路徑上訪問的節點和對應的步數。 例如A -> B -> C -> A,如果從A開始,Map會變成{A -> 1, B -> 2, C -> 3},再次進入A時,步驟變為4,因此循環的長度是 4 - 1 = 3
(4) Set<GraphNode> visited
:包含已被充分探索的graphNodes。
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。
誰能給我一些關於為什么上述算法錯誤的提示?
考慮下圖:
D -- A
/ | |
E | |
\ | |
C -- B
現在,假設您在節點 A 啟動 DFS 並按順序訪問節點 B,然后是 C,然后是 D,然后是 E。除非我誤解了您的代碼在做什么,否則我不相信這個訪問順序會允許您發現最長的周期 A、B、C、E、D、A,因為一旦您訪問了 D,您就為其分配了錯誤的深度並切斷了返回 A 的路徑。
我認為問題是什么是“基本循環”。 如果循環一次訪問所有點,則 DFS 是好的。 但這是問題:
A---B
|\ /|
| E |
|/ \|
C---D
假設方向:
A -> B
乙 -> 丁,乙
C -> D
D -> E,A
E -> C
DFS 會發現最長的周期是 5,A->B->E->C->D->A 但最長的周期應該是 A->B->E->C->D->E->A。 也許你應該嘗試新的觀點
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.