python編程練習---有向加權圖,最短路徑(固定起點)



求從start到end的最短路徑
涉及到無回環路徑的情況(A-》B、B-》A),可以使用dijkstra算法(狄克斯特拉)
算法步驟詳解:
1、找出“最便宜”的節點,即可在最短時間內到達的節點(從start出發,最短距離的節點)
2、更新通過該節點,到其他鄰居節點的最短距離
3、重復這個過程,直到對圖中的每個幾點都這樣做了
4、計算最短路徑

1、根據圖片各節點之間的距離,建立數據關系

graph表示各節點可達節點的距離

graph = {}
graph["start"] = {}
graph["start"]["A"] = 5
graph["start"]["B"] = 2
graph["A"] = {}
graph["A"]["C"] = 4
graph["A"]["D"] = 2
graph["B"] = {}
graph["B"]["A"] = 1
graph["B"]["E"] = 6
graph["C"] = {}
graph["C"]["end"] = 2
graph["D"] = {}
graph["D"]["end"] = 1
graph["E"] = {}
graph["E"]["D"] = 1
graph["E"]["end"] = 4
graph["end"] = {}

2、建立一個數據結構,用來存儲從start節點,到各個節點的距離,不知道距離的節點,先記做無窮大(math.inf)

infinity = math.inf
costs = {}
costs["A"] = 6
costs["B"] = 2
costs["C"] = infinity
costs["D"] = infinity
costs["E"] = infinity
costs["end"] = infinity

3、建立一個數據結構,用來存儲從start節點,到各個節點最短距離時,該節點的父節點

parents = {}
parents["A"] = "start"
parents["B"] = "start"
parents["C"] = None
parents["D"] = None
parents["E"] = None
parents["F"] = None

根據節點圖,初始化的3個數據結構已經創建完成
計算start到各個節點的最小距離,就可以按照算法步驟來完成
1、首先查找start節點出發可達的最小距離的節點返回該節點

#如果節點被檢查過,則添加到processed中
processed = []

def find_lowest_cost_node(costs):
    lowest_cost = infinity      #未檢查過的節點最小距離
    lowest_cost_node = None     #節點初始化
    for node in costs:          #遍歷節點
        cost = costs[node]      #返回start到節點的距離
        if cost < lowest_cost and node not in processed:      #如果節點距離小於最小距離,並且該節點沒有被檢查過,那么設置最小距離為當前被檢查的節點的最小距離,最小距離節點為當前檢查的節點
            lowest_cost = cost
            lowest_cost_node = node
    return lowest_cost_node     #返回最小節點

2、計算從start節點,經過最小距離節點到最小距離節點的鄰節點的距離,並更新相關數據結構。依次對剩余未檢查的節點進行遍歷
例如:start到B,最小距離為2,先檢查B節點,然后計算start經過B到B的鄰節點A、E的距離
start->B->A 的距離為2+1=3,小於start->A(6),所以,需要更新costs中start到A的最小距離為3,parents中,A的父節點為B

#首先找到最小距離的節點
node= find_lowest_cost_node(costs)

#當節點不為空時
while node is not None:
    cost = costs[node]      #start到node的距離
    neighbors = graph[node]      #node的鄰節點
    for n in neighbors.keys():      #遍歷鄰節點      
        new_cost = cost + neighbors[n]      #start經過node到鄰節點的距離
        if costs[n] > new_cost:             #判斷start經過node到鄰節點的距離與start到鄰節點的最小距離,如果小於就更新最小距離與父節點
            costs[n] = new_cost
            parents[n] = node
    processed.append(node)                  #被檢查的節點添加到數組中
    node = find_lowest_cost_node(costs)     #遍歷

最終打印parents、costs,就可以知道從start到各個節點的最小距離以及最小距離的父節點

print(parents)
print(costs)
{'A': 'B', 'B': 'start', 'C': 'A', 'D': 'A', 'E': 'B', 'end': 'D'}
{'A': 3, 'B': 2, 'C': 7, 'D': 5, 'E': 8, 'end': 6}

從中可以看出start到end的最小距離為6,父節點關系:end->D->A->B->start(路徑為:start-B-A-D-end)


免責聲明!

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



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