[英]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.