簡體   English   中英

如何檢測字典中的循環?

[英]How to detect a cycle in a dictionary?

我有以下字典,第一個數字是節點,后跟一個由鄰居組成的元組,然后是邊權重(某些節點有多個鄰居和權重):

dictionary = {1: [(2, 3), (4, 5), (6, 2)], 2: [(3, -4)], 3: [(8, 4)], 4: [(5, 6)], 5: [(4, -3), (8, 8)], 6: [(7, 3)], 7: [(6, -6), (8, 7)]}

我將如何使用深度優先搜索 (DFS) 來檢測是否存在循環? 出於測試目的,字典會經常更改,因此有些可能有循環,有些可能沒有。 我是 python 的新手,不明白如何實施 DFS 來檢查周期。 我有以下 DFS 代碼:

visited = set() # Set to keep track of visited nodes of graph.

def dfs(visited, dictionary, node):  #function for dfs
    if node not in visited:
        print (node)
        visited.add(node)
        for neighbour in dictionary[node]:
            dfs(visited, dictionary, neighbour)

然后我調用 function: dfs(visited, dictionary, '1')

但我收到錯誤KeyError: '1' 我也不確定如何使用此代碼來檢測周期。

首先,我們考慮基本情況。 在這種情況下,我們希望評估圖是否具有循環。 當檢測到一個循環時,function 應該返回真,如果在檢查所有邊之后不存在這樣的循環,則返回假。

dictionary = {1: [(2, 3)], 2: [], 3: [(4, 4)], 4: [(3, 6)]}

def DFS(visited, dictionary, node):
    if node in visited:
        return True
    else:
        for neighbour, weight in dictionary[node]:
            if DFS(visited | {node}, dictionary, neighbour):
                return True
        return False

print(f"{DFS(set(), dictionary, 1)=}") # False

深度優先搜索將檢查來自單個節點的所有路徑,在回溯之前盡可能地探索。 如果遇到以前見過的節點,搜索將停止,function 返回 true。 如果起始節點的所有路徑都已用盡,則返回 false。 這只會檢測節點 1 是否參與任何循環。

然而,這種方法不足以檢測不涉及起始節點的循環。 在上面的例子中,DFS 不會找到節點 3 和 4 之間的循環,因為它從 1 開始搜索。

為了解決這個問題,我們可以編寫另一個 function 來檢查所有具有 DFS 的節點。

def containsCycle(dictionary):
    for node in dictionary.keys():
        if DFS(set(), dictionary, node):
            return True
    return False

print(f"{containsCycle(dictionary)=}") # True
dictionary = {1: [(2, 3), (4, 5), (6, 2)], 2: [(3, -4)], 
              3: [(8, 4)], 4: [(5, 6)], 5: [(4, -3), (8, 8)], 
              6: [(7, 3)], 7: [(6, -6), (8, 7)]}

上面的字典有一條到節點 8 的邊,但字典中沒有該節點的條目。 這將導致錯誤。 為了解決這個問題,我們可以在遞歸 function 中添加一個保護子句。

def DFS(visited, dictionary, node):
    if node in visited:
        return True
    elif node not in dictionary: # Guard clause
        return False
    else:
        for neighbour, weight in dictionary[node]:
            if DFS(visited | {node}, dictionary, neighbour):
                return True
        return False

暫無
暫無

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

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