有向圖_節點間路徑路徑--python數據結構


字典創建有向圖,查找圖節點之間的路徑,最短路徑,所有路徑

 

"""
參考文檔:
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)

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM