字典創建有向圖,查找圖節點之間的路徑,最短路徑,所有路徑
"""
參考文檔:
https://www.python.org/doc/essays/graphs/
"""
# 此有向圖 有六個節點 (A-F) 和八個弧
"""
它可以由以下Python數據結構表示:
這是一個字典,其鍵是圖形的節點。
對於每個鍵,相應的值是一個列表,其中包含由來自此節點的直接連接的節點;即兩點直接連接
這很簡單(更簡單的是,節點可以用數字而不是名稱來表示,但名稱更方便,可以很容易地攜帶更多信息,例如城市名稱)。
"""
from collections import deque
graph = {
'A': ['B', 'C'],
'B': ['C', 'D'],
'C': ['D'],
'D': ['C'],
'E': ['F'],
'F': ['C'],
}
# 找到一個符合條件的路徑
"""讓我們編寫一個簡單的函數來確定兩個節點之間的路徑。
它采用圖形以及開始和結束節點作為 參數。
它將返回包含路徑的節點列表(包括開始節點和結束節點)。如果找不到路徑,則返回 None。
同一節點在返回的路徑上不會出現多次(即它不會包含循環)。
該算法使用了一種稱為回溯的重要技術:它依次嘗試每種可能性,直到找到解決方案。
"""
def find_path(graph, start, end, path=[]):
path = path + [start] # 路徑,每一次遞歸調用時,把當前結點加入已經訪問的集合中去
print("path:%s" % path)
if start == end:
return path
if start not in graph: # 僅存在此節點 不作為弧頭出現,僅作為弧尾[數據結構唐朔飛]
return None # 遞歸結束的條件
print("graph[{}]:{}".format(start, graph[start]))
for node in graph[start]: # 依次訪問start的鄰接頂點node
if node not in path: # 同一節點在返回的路徑上不會出現多次
print("node:{}".format(node))
newpath = find_path(graph, node, end, path) # 遞歸調用時傳入參數path
# print("newpath:{}".format(newpath))
# newpath=False
if newpath:
# print("if--newpath:{}".format(newpath))
return newpath # 找到一條路徑便結束循環
return None
"""
更改上函數以返回所有路徑的列表(不帶循環),而不是它找到的第一個路徑
"""
# 找到所有的路徑
def find_all_paths(graph, start, end, path=[]):
path = path + [start]
if start == end:
return [path]
if start not in graph:
return []
paths = []
for node in graph[start]:
if node not in path:
newpaths = find_all_paths(graph, node, end, path)
for newpath in newpaths:
paths.append(newpath) # 找到的路徑加入路徑列表
return paths
# 最短路徑
def find_shortest_path(graph, start, end, path=[]):
path = path + [start]
if start == end:
return path
if start not in graph:
return None
shortest = None
for node in graph[start]:
if node not in path:
newpath = find_shortest_path(graph, node, end, path)
if newpath:
if shortest is None or len(newpath) < len(shortest):
# if not shortest or len(newpath) < len(shortest):
shortest = newpath
return shortest
"""
find_shortest_path可以使用BFS[廣度優先搜索]在線性時間內完成。
此外,線性BFS更簡單
"""
# path = find_path(graph, 'D', 'C')
# print(path)
# #---------------------------
# paths = find_all_paths(graph, 'A', 'C')
# print(paths)
# row = 1
# for path in paths:
# print(row, end=":")
# print(path)
# row = row + 1
# #---------------------------
shortest = find_shortest_path(graph, 'A', 'D')
print(shortest)
