簡體   English   中英

使用DFS檢測無向圖中的循環

[英]Detecting a cycle in an undirected graph using DFS

我有以下代碼,它是對DFS的修改,用於檢測無向圖是否具有循環。

graph = {
    'A' : set(['B', 'C']),
    'B' : set(['D', 'E', 'A']),
    'C' : set(['A', 'F']),
    'D' : set(['B']),
    'E' : set(['B', 'F']),
    'F' : set(['C','E'])
}

def find_cycle(graph, start):
    colors = { node : "WHITE" for node in graph }
    colors[start] = "GRAY"
    stack = [start]
    while stack:
        for neighbor in graph[stack[-1]]:
            if colors[neighbor] == "GRAY":
                return True
            elif colors[neighbor] == "WHITE":
                colors[neighbor] = "GRAY"
                stack.append(neighbor)
            else:
                colors[neighbor] = "BLACK"
                stack.pop()
     return False

無論我的圖是什么樣,它總是返回true,而我無法弄清楚我在做什么錯。 當我在紙上跟蹤該算法時,該算法有效,但實現方式無法轉換為有效代碼。

您的算法不適用於無向圖。 您很容易將周期檢測為A和B之間的第一個邊緣(B是A的鄰居,A是B的鄰居)。

您的代碼以鄰居的身份訪問了您剛來自的節點,因此您在同一邊上來回移動,卻發現您已經訪問了您實際來自的節點。 但是該算法錯誤地得出結論,這代表一個循環。

因此,僅檢查鄰居是否已被訪問還不夠。 如果相應的邊緣之前尚未移動過,則僅表示一個循環。

使算法起作用的一種方法是將邊緣存儲在堆棧中,而不僅僅是節點。 然后,您可以輕松地檢查鄰居是否在邊緣的另一端,然后忽略它:

def find_cycle(graph, start):
    colors = { node : "WHITE" for node in graph }
    colors[start] = "GRAY"
    stack = [(None, start)] # store edge, but at this point we have not visited one
    while stack:
        (prev, node) = stack.pop()  # get stored edge
        for neighbor in graph[node]:
            if neighbor == prev:
                pass # don't travel back along the same edge we came from
            elif colors[neighbor] == "GRAY":
                return True
            else: # can't be anything else than WHITE...
                colors[neighbor] = "GRAY"
                stack.append((node, neighbor)) # push edge on stack
    return False

請注意,您在問題中顯示的圖形具有一個循環:

   A---C 
  /     \
 B---E---F

例如,如果刪除C和F之間的連接,則上面的代碼將返回False

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM