字典創建有向圖,查找圖節點之間的路徑,最短路徑,所有路徑
""" 參考文檔: 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)