我們如何檢測有向圖是循環的?我想過使用廣度優先搜索,但我不確定。有任何想法嗎?如何檢測有向圖是循環的?
回答
通常使用深度優先搜索來代替。 我不知道BFS是否適用。
在DFS中,根據訪問順序構建生成樹。如果樹中的一個節點的祖先被訪問(即創建了一個後沿),那麼我們檢測到一個循環。
有關更詳細的解釋,請參閱http://www.cs.nyu.edu/courses/summer04/G22.1170-001/6a-Graphs-More.pdf。
BFS或DFS在這個問題上具有相同的複雜性(運行時)和適用性(相同的結果)。唯一的區別在於節點的訪問順序。 – darlinton 2010-03-26 17:46:26
鏈接中指示的頁面上的最後一條語句是基於邊和頂點數的拓撲語句: 「圖G中沒有循環的最大可能邊數爲| V | -1。 「 對於*未定向*圖,對於*定向*圖,這是正確的,如原始問題所示。對於有向圖,「鑽石繼承」圖提供了一個反例(4個節點和4個邊形成一個「循環」,但不是可以通過跟隨箭頭遍歷的「循環」)。 – Peter 2010-03-29 16:49:32
如果最後一條評論不清楚 - 我說接受的答案對於無向圖而言是足夠的,但對於有向圖而言是錯誤的*(如問題中指定的)。 – Peter 2010-03-29 18:44:42
另一個簡單的解決方案是標記和掃描方法。基本上,對於樹中的每個節點,將其標記爲「已訪問」,然後轉到其子節點。如果你看到一個設置了「visted」標誌的節點,你就知道有一個循環。
如果修改圖形以包含「訪問」位是不可能的,則可以使用一組節點指針。要將節點標記爲已訪問,請在該集中放置一個指向它的指針。如果指針已經在集合中,就有一個循環。
該解決方案與KennyTM提供的解決方案類似,但對問題更好。問題在於識別週期,所以標記和掃描是一種很好的方法。正如Kenny所建議的,構建生成樹是解決問題的一種更復雜的方法,因爲您正在使用生成樹的概念。最後,它幾乎都是一樣的。 – darlinton 2010-03-26 17:48:56
@Rakis:它會誤認http://en.wikipedia.org/wiki/File:Diamond_inheritance.svg爲一個循環嗎? – kennytm 2010-03-26 18:26:26
@KennyTM:是的,它會的。如果您使用DFS或BFS探索圖中的節點,則無關緊要 - 您將以同樣的方式得到相同的錯誤答案。跟蹤哪些節點已被訪問以識別週期是不夠的。所以我會從Rakis中扣除一點答案(但我的名聲太微不足道了)。 – Peter 2010-03-29 16:42:16
你真正需要的是什麼,我相信,在這裏所描述的一樣一個一個拓撲排序算法:
http://en.wikipedia.org/wiki/Topological_sorting
如果有向圖有一個週期,則算法將失敗。
的意見/回答說,我到目前爲止看到似乎缺少一個事實,即在定向圖可能有不止一種方法從節點X獲得,而不存在以節點Y的任何(導演)圖中的週期。
方法:1
如何檢測一個週期級別沒有分配。例如:考慮下面的圖表。 (B,C)B-> D D - >(E,F)E,F - >(G)E-> D當您執行DFS開始時,爲您訪問的節點分配一個級別no = 0)。級別no =父節點+ 1。所以A = 0,B = 1,D = 2,F = 3,G = 4,則遞歸達到D,所以E = 3。不要標記G的等級(G已經是一個沒有被分配的等級比E更高的等級)現在E也具有對D的邊緣。因此,等級化將會說D應該得到4的等級no。但是D已經具有分配的「較低等級」到它2.因此,任何時候你試圖級別數分配到一個節點,而這樣做已經有設置爲它一個較低的水平數DFS,你知道有向圖有一個週期..
approach2:
使用3種顏色。白色,灰色,黑色。只有白色節點纔會着色,當您沿DFS走向時,白色節點變爲灰色,當遞歸展開時(處理所有子節點),將灰色節點變爲黑色。如果不是所有的孩子都處理完畢,並且你打了一個灰色節點,那就是一個循環。 例如:全部白色以直接上圖開始。顏色A,B,D,F,G顏色爲白色灰色。 G是葉子,所以所有的孩子都把它染成灰色變成黑色。遞歸到F(所有處理過的孩子)將它染成黑色。現在你到達D,D有未加工的孩子,所以顏色E灰色,G已經着黑色,所以不要進一步下去。 E也有邊緣到D,所以在仍然處理D(D仍然是灰色)的時候,你會發現一個邊緣回到D(一個灰色節點),就會檢測到一個週期。
對給定圖形的拓撲排序測試將引導您找到解決方案。如果topsort的算法,即邊緣總是以一種方式定向失敗,那麼這意味着圖形包含循環。
使用DFS搜索如有路徑循環
class Node<T> { T value; List<Node<T>> adjacent; }
class Graph<T>{
List<Node<T>> nodes;
public boolean isCyclicRec()
{
for (Node<T> node : nodes)
{
Set<Node<T>> initPath = new HashSet<>();
if (isCyclicRec(node, initPath))
{
return true;
}
}
return false;
}
private boolean isCyclicRec(Node<T> currNode, Set<Node<T>> path)
{
if (path.contains(currNode))
{
return true;
}
else
{
path.add(currNode);
for (Node<T> node : currNode.adjacent)
{
if (isCyclicRec(node, path))
{
return true;
}
else
{
path.remove(node);
}
}
}
return false;
}
的
您尚未定義函數isCyclic。 – 2015-12-04 16:47:26
此代碼在此輸入上失敗:4 - > 1-> 2-> 3。它會失敗,如果你開始從節點1探索。 – 2016-07-03 20:34:05
找到如何解決:設置
- 1. 檢測循環有向圖中的多個循環
- 2. 如何使用Scheme檢查無向圖是否有循環?
- 3. 如何檢測定向圖中週期的循環
- 4. 檢測一個無向圖中是否存在一個循環
- 5. 有向圖中的循環
- 6. 有向圖中的循環
- 7. 瀏覽器重定向循環檢測
- 8. BFS循環檢測
- 9. QuickGraph:循環檢測
- 10. C#如何檢測循環引用?
- 11. 有沒有自循環的無向圖?
- 12. 如何檢查無向圖中循環的存在性?
- 13. 如何將無向非循環圖轉換爲有向無環圖?
- 14. 檢測圖中是否存在負循環的最快算法
- 15. 查找有向圖和無向圖中的所有循環
- 16. prolog中有向圖的循環
- 17. 使用BFS循環檢測
- 18. 檢測循環引用
- 19. 如何做循環檢索流圖像?
- 20. 循環內循環 - 在autohotkey中檢測循環結束
- 21. 如何檢測向量中的SFML循環與精靈之間的衝突?
- 22. 檢測是否有下一個,而在每個循環中
- 23. 如何檢查循環中的所有內容是否正確?
- 24. 循環枚舉多邊有向圖
- 25. 定向循環圖有葉嗎?
- 26. 如何檢測來自url的圖像是縱向還是橫向(Android)
- 27. 是否有可能向後循環?
- 28. 檢測服務器端的無限HTTP重定向循環
- 29. 如何向後循環?
- 30. 如何爲反向循環?
可能重複[我怎樣檢查是否有向圖是無環?](http://stackoverflow.com/questions/583876/how- do-i-check-if-a-directed-graph-is-acyclic) – 2015-01-14 12:43:01
我剛剛在相關的StackOverflow線程上發佈了Scala的通用FP解決方案:http://stackoverflow.com/a/36144158/501113 – chaotic3quilibrium 2016-03-22 00:43:29