日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

用图讲解狄克斯特拉(DiskStra)算法,python实现 。

發(fā)布時(shí)間:2024/9/30 python 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用图讲解狄克斯特拉(DiskStra)算法,python实现 。 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最短路徑

在一個(gè)帶權(quán)圖中,頂點(diǎn)V0到圖中任意一個(gè)頂點(diǎn)Vi的一條路徑所經(jīng)過(guò)邊上的權(quán)值之和,定義為該路徑的帶權(quán)路徑長(zhǎng)度,把帶權(quán)路徑最短的那條路徑稱為最短路徑。
如圖所示,求雙子峰到金門大橋的最短距離。

此類問(wèn)題要用到狄克斯特拉(DiskStra)算法

使用狄克斯特拉(DiskStra)算法

圖中每個(gè)數(shù)字都是時(shí)間,為此找出從起點(diǎn)到終點(diǎn)用時(shí)最短的路徑。

如果你使用廣度優(yōu)先搜索,廣度優(yōu)先搜索算法BFS講解以及python 實(shí)現(xiàn)
你將得到下面這條段數(shù)最少的路徑。

這條路徑耗費(fèi)7分鐘,我們接下來(lái)找找還有沒(méi)有更短的路徑。
狄克斯特拉(DiskStra)算法 包含4個(gè)步驟:

  • 找出可在最短時(shí)間內(nèi)到達(dá)的點(diǎn)
  • 更新該節(jié)點(diǎn)的鄰居的開(kāi)銷
  • 重復(fù)計(jì)算該過(guò)程,直到對(duì)所有節(jié)點(diǎn)都做了
  • 計(jì)算最終路徑
  • 第一步:你站在起點(diǎn),可以走的點(diǎn)是A,B。到達(dá)A需要6分鐘,到達(dá)B需要2分鐘,其他節(jié)點(diǎn)不能到達(dá),設(shè)為無(wú)窮。

    第二步:因?yàn)槠瘘c(diǎn)到B最近,然后計(jì)算B前往各鄰居的距離
    B到A的距離是3,我們找到一條前往A點(diǎn)的更短路徑5,從起點(diǎn)直接前往A點(diǎn)距離是6,則更新庫(kù)中起點(diǎn)到A的距離。

    對(duì)于節(jié)點(diǎn)B的鄰居,如果找到前往它的更短路徑,就更新其開(kāi)銷,在這里我們找到了:前往A點(diǎn)的更短路徑,時(shí)間由6分鐘縮短到了5分鐘;前往終點(diǎn)的更短路徑,時(shí)間由無(wú)窮大縮短到7分鐘。

    第三步:重復(fù)
    重復(fù)第一步,找出最短時(shí)間可以到達(dá)的點(diǎn),前面對(duì)節(jié)點(diǎn)B執(zhí)行了第二步,除B點(diǎn)外,還有節(jié)點(diǎn)A

    重讀第二步,更新節(jié)點(diǎn)A所有鄰居的開(kāi)銷

    你發(fā)現(xiàn)前往終點(diǎn)的時(shí)間為6分鐘。

    對(duì)每個(gè)節(jié)點(diǎn)都應(yīng)用狄克斯特拉(DiskStra)算法,現(xiàn)在知道前往B節(jié)點(diǎn)2分鐘,A分鐘,終點(diǎn)6分鐘。

    狄克斯特拉(DiskStra)算法適用于有向無(wú)環(huán)圖。

    算例1實(shí)現(xiàn)

    以圖為例

    第一步:解決這個(gè)問(wèn)題,需要準(zhǔn)備三個(gè)散列表

    第一個(gè)散列表表示圖,依次是父節(jié)點(diǎn),子節(jié)點(diǎn),權(quán)重。第一個(gè)散列表圖可以用散列表嵌套表示。

    """ 、、、、、、 第一個(gè)散列表 用于表示圖 、、、、、、 """ graph={} #起點(diǎn) 到各鄰居的關(guān)系 graph["start"]={} graph["start"]["a"]=6 graph["start"]["b"]=2 #print(graph["start"].keys())#dict_keys(['a', 'b']) #節(jié)點(diǎn)a到各鄰居關(guān)系 graph["a"]={} graph["a"]["fin"]=1#節(jié)點(diǎn)b到各鄰居關(guān)系 graph["b"]={} graph["b"]["a"]=3 graph["b"]["fin"]=5#終點(diǎn)與各鄰居關(guān)系 graph["fin"]={}#終點(diǎn)沒(méi)有鄰居

    第二個(gè)散列表為初始時(shí)起點(diǎn)出發(fā)到各節(jié)點(diǎn)的距離,隨著算法進(jìn)行需要不斷更新。

    """ 第二個(gè)散列表 節(jié)點(diǎn)的開(kāi)銷。節(jié)點(diǎn)的開(kāi)銷表示起點(diǎn)出發(fā)到該節(jié)點(diǎn)需要多少時(shí)間""" infinity=float("inf")#無(wú)窮大 costs={} costs['a']=6 costs['b']=2 costs['fin']=infinity

    第三個(gè)散列表。左邊為子節(jié)點(diǎn),右邊為父節(jié)點(diǎn),用來(lái)表示路徑。隨著算法進(jìn)行需要不斷更新,是針對(duì)出發(fā)點(diǎn)建立的

    """ 第三個(gè)散列表 存儲(chǔ) 路徑 . parents['a']="start"表示節(jié)點(diǎn)a的上一節(jié)點(diǎn)是start,如果后面發(fā)現(xiàn)更短路徑,可以修改為parents['a']=b""" parents={} parents['a']="start" parents['b']="start" parents['fin']=None#出發(fā)點(diǎn)不能直接到達(dá)

    第二步:需要一個(gè)數(shù)組,存儲(chǔ)已經(jīng)處理過(guò)的節(jié)點(diǎn)

    """ 需要一個(gè)數(shù)組,存儲(chǔ)已經(jīng)處理過(guò)的節(jié)點(diǎn) """ processed=[]

    第三步:最小開(kāi)銷節(jié)點(diǎn)函數(shù)

    """ 開(kāi)銷最小的函數(shù) """ def find_lowest_cost_node(costs):lowest_cost=float('inf')lowest_cost_node=Nonefor node in costs:#遍歷每個(gè)節(jié)點(diǎn)cost=costs[node]if cost<lowest_cost and node not in processed:#如果當(dāng)前節(jié)點(diǎn)小于最小開(kāi)銷,且沒(méi)有處理過(guò)lowest_cost_node=node #則將該節(jié)點(diǎn)設(shè)為最小開(kāi)銷節(jié)點(diǎn)lowest_cost=cost#更新最小開(kāi)銷return lowest_cost_node

    第四步:DiskStra算法

    """ DiskStra算法""" node=find_lowest_cost_node(costs) #在未處理的節(jié)點(diǎn)中找到開(kāi)銷最小的節(jié)點(diǎn),即離出發(fā)點(diǎn)最近的點(diǎn) while node is not None: #這個(gè)循環(huán)表示所有節(jié)點(diǎn)處理過(guò)才會(huì)結(jié)束cost=costs[node]neighbors=graph[node]for n in neighbors.keys():#遍歷當(dāng)前節(jié)點(diǎn)的所有鄰居new_cost=cost+neighbors[n]if costs[n]>new_cost:#如果經(jīng)當(dāng)前節(jié)點(diǎn)離該鄰居更近costs[n]=new_cost#就更新該節(jié)點(diǎn)的開(kāi)銷parents[n]=node #同時(shí)將該鄰居的父節(jié)點(diǎn)設(shè)置為該節(jié)點(diǎn)processed.append(node)#將該節(jié)點(diǎn)標(biāo)記為處理過(guò)node=find_lowest_cost_node(costs) #查找接下來(lái)要循環(huán)處理的點(diǎn),并循環(huán)

    全部代碼

    """ 第一個(gè)散列表 用于表示圖 """ graph={} #起點(diǎn) 到各鄰居的關(guān)系 graph["start"]={} graph["start"]["a"]=6 graph["start"]["b"]=2 #print(graph["start"].keys())#dict_keys(['a', 'b']) #節(jié)點(diǎn)a到各鄰居關(guān)系 graph["a"]={} graph["a"]["fin"]=1#節(jié)點(diǎn)b到各鄰居關(guān)系 graph["b"]={} graph["b"]["a"]=3 graph["b"]["fin"]=5#終點(diǎn)與各鄰居關(guān)系 graph["fin"]={}#終點(diǎn)沒(méi)有鄰居""" 第二個(gè)散列表 節(jié)點(diǎn)的開(kāi)銷。節(jié)點(diǎn)的開(kāi)銷表示起點(diǎn)出發(fā)到該節(jié)點(diǎn)需要多少時(shí)間,每個(gè)節(jié)點(diǎn)都要列出來(lái)""" infinity=float("inf")#無(wú)窮大 costs={} costs['a']=6 costs['b']=2 costs['fin']=infinity""" 第三個(gè)散列表 存儲(chǔ) 路徑 . parents['a']="start"表示節(jié)點(diǎn)a的上一節(jié)點(diǎn)是start,如果后面發(fā)現(xiàn)更短路徑,可以修改為parents['a']=b,每個(gè)節(jié)點(diǎn)都要列出來(lái)""" parents={} parents['a']="start" parents['b']="start" parents['fin']=None#出發(fā)點(diǎn)不能直接到達(dá)""" 需要一個(gè)數(shù)組,存儲(chǔ)已經(jīng)處理過(guò)的節(jié)點(diǎn) """ processed=[]""" 開(kāi)銷最小的函數(shù) """ def find_lowest_cost_node(costs):lowest_cost=float('inf')lowest_cost_node=Nonefor node in costs:#遍歷每個(gè)節(jié)點(diǎn)cost=costs[node]if cost<lowest_cost and node not in processed:#如果當(dāng)前節(jié)點(diǎn)小于最小開(kāi)銷,且沒(méi)有處理過(guò)lowest_cost_node=node #則將該節(jié)點(diǎn)設(shè)為最小開(kāi)銷節(jié)點(diǎn)lowest_cost=cost#更新最小開(kāi)銷return lowest_cost_node""" DiskStra算法""" node=find_lowest_cost_node(costs) #在未處理的節(jié)點(diǎn)中找到開(kāi)銷最小的節(jié)點(diǎn),即離出發(fā)點(diǎn)最近的點(diǎn) while node is not None: #這個(gè)循環(huán)表示所有節(jié)點(diǎn)處理過(guò)才會(huì)結(jié)束cost=costs[node]neighbors=graph[node]for n in neighbors.keys():#遍歷當(dāng)前節(jié)點(diǎn)的所有鄰居new_cost=cost+neighbors[n]if costs[n]>new_cost:#如果經(jīng)當(dāng)前節(jié)點(diǎn)離該鄰居更近costs[n]=new_cost#就更新該節(jié)點(diǎn)的開(kāi)銷parents[n]=node #同時(shí)將該鄰居的父節(jié)點(diǎn)設(shè)置為該節(jié)點(diǎn)processed.append(node)#將該節(jié)點(diǎn)標(biāo)記為處理過(guò)node=find_lowest_cost_node(costs) #查找接下來(lái)要循環(huán)處理的點(diǎn),并循環(huán)#打印結(jié)果 print('costs',costs) print('parents',parents)

    流程圖解

    找到開(kāi)銷最少的點(diǎn)

    獲取該節(jié)點(diǎn)的開(kāi)銷和鄰居

    遍歷鄰居

    每個(gè)節(jié)點(diǎn)都要開(kāi)銷,開(kāi)銷指從起點(diǎn)到該節(jié)點(diǎn)需要多長(zhǎng)時(shí)間,在這里,將計(jì)算從起點(diǎn)到B再到A的開(kāi)銷,而不是直接到A的開(kāi)銷

    和原始開(kāi)銷進(jìn)行對(duì)比

    找到一條前往節(jié)點(diǎn)A的更短路徑,更新節(jié)點(diǎn)A的開(kāi)銷 這條路徑由B到A,由此更新節(jié)點(diǎn)A的父節(jié)點(diǎn)

    現(xiàn)在回到for循環(huán),下一個(gè)鄰居是終點(diǎn)

    經(jīng)節(jié)點(diǎn)B前往終點(diǎn)需要7分鐘,

    原始終點(diǎn)節(jié)點(diǎn)開(kāi)銷為無(wú)窮大,現(xiàn)在7分鐘,更新終點(diǎn)節(jié)點(diǎn)的開(kāi)銷和父節(jié)點(diǎn)

    現(xiàn)在將節(jié)點(diǎn)B設(shè)為被處理過(guò)的

    接下來(lái)要處理的點(diǎn)

    獲取節(jié)點(diǎn)A的開(kāi)銷和鄰居

    節(jié)點(diǎn)A只有一個(gè)鄰居,終點(diǎn)。當(dāng)前前往終點(diǎn)需要7分鐘,經(jīng)過(guò)節(jié)點(diǎn)A需要多久,見(jiàn)圖

    更短,更新終點(diǎn)的開(kāi)銷和父節(jié)點(diǎn)

    節(jié)點(diǎn)A被添加進(jìn)處理過(guò)的。
    接下來(lái)要處理的點(diǎn)為終點(diǎn)fin。
    終點(diǎn)fin沒(méi)有鄰居,不更新,然后顯示終點(diǎn)也被添加進(jìn)處理過(guò)的。
    node變?yōu)榭?#xff0c;退出while循環(huán)。結(jié)束。

    如果要改變起點(diǎn),如起點(diǎn)改到A,再來(lái)探討該問(wèn)題。只需修改costs和parents散列表即可。
    算例1借鑒:《算法圖解》

    算例2實(shí)現(xiàn)

    算例1用到的數(shù)據(jù)結(jié)構(gòu)是散列表,本例子用矩陣來(lái)做。

    第一步:定義圖和拓?fù)浣Y(jié)構(gòu)

    """ 一.定義圖 """ ### ====================給一個(gè)所有節(jié)點(diǎn)的列表 list_nodes_id = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; ### ==================== 給一個(gè)拓?fù)涞某?shù)矩陣. fin= float('inf') # 無(wú)窮大。這意味著沒(méi)有聯(lián)系。 ### fin_topo是表示拓?fù)涞亩S鄰接矩陣 fin_topo = [[fin, 2.9, 2.5, fin, 2, fin, 1.8, 3, 1.8, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 0[2.9, fin, 1.3, fin, fin, 1.7, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 1[1, 1, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 2[fin, fin, 1, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 3[1, fin, fin, 1, fin, fin, fin, fin, fin, 1, 1, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 4[fin, 1, fin, fin, fin, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 5[1, fin, fin, fin, fin, 1, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 6[1, fin, fin, fin, fin, fin, 1, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 7[1, fin, fin, fin, fin, fin, fin, 1, fin, 1, fin, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin], # 8[fin, fin, fin, fin, 1, fin, fin, fin, 1, fin, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 9[fin, fin, fin, fin, 1, fin, fin, fin, fin, fin, fin, 1, fin, 1, fin, fin, fin, fin, fin, fin, fin], # 10[fin, fin, fin, fin, 1, fin, fin, fin, fin, 1, 1, fin, fin, 1, 1, fin, fin, fin, fin, fin, fin], # 11[fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, fin, fin, fin, fin, 1, fin, fin, fin, fin, fin, fin], # 12[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, 1, fin, fin, 1, fin, fin, 1, 1, fin, fin], # 13[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, 1, 1, fin, 1, 1, fin, fin, fin, fin], # 14[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, 1, fin, 1, 1, fin], # 15[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, 1, fin, fin, fin, fin, 1], # 16[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, fin, fin, fin, 1, fin, fin], # 17[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, 1, fin, 1, fin, 1, fin], # 18[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, fin, 1, fin, 1], # 19[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, fin, 1, fin], # 20 ]### --- 讀取拓?fù)?#xff0c;并生成給定拓?fù)渲械乃羞叀?/span> edges = [] for i in range(len(fin_topo)):for j in range(len(fin_topo[0])):if i != j and fin_topo[i][j] != fin:edges.append((i, j, fin_topo[i][j])) ### (i,j) 是一個(gè)鏈接;fin_topo[i][j]這里是1,鏈接的長(zhǎng)度(i,j). #print(edges) #[(0, 1, 2.9), (0, 2, 2.5), (0, 4, 2), (0, 6, 1.8), (

    edges

    第二步 算法

    """算法實(shí)現(xiàn)""" from collections import defaultdict from heapq import *#heapq 堆,一般指最小堆 """ heap = [1,3,4,2,6,8,9] heapq.heapify(heap) # heap = [1,2,4,3,6,8,9] """ """ g {0: [(2.9, 1), (2.5, 2), (2, 4), (1.8, 6), (3, 7), (1.8, 8)], 1: [(2.9, 0), (1.3, 2), (1.7, 5)], 2: [(1, 0), (1, 1), (1, 3)], 3: [(1, 2), (1, 4)], 4: [(1, 0), (1, 3), (1, 9), (1, 10), (1, 11)], 5: [(1, 1), (1, 6)], 6: [(1, 0), (1, 5), (1, 7)], 7: [(1, 0), (1, 6), (1, 8)], 8: [(1, 0), (1, 7), (1, 9), (1, 12)], 9: [(1, 4), (1, 8), (1, 11)], 10: [(1, 4), (1, 11), (1, 13)], 11: [(1, 4), (1, 9), (1, 10), (1, 13), (1, 14)], 12: [(1, 8), (1, 14)], 13: [(1, 10), (1, 11), (1, 14), (1, 17), (1, 18)], 14: [(1, 11), (1, 12), (1, 13), (1, 15), (1, 16)], 15: [(1, 14), (1, 16), (1, 18), (1, 19)], 16: [(1, 14), (1, 15), (1, 20)], 17: [(1, 13), (1, 18)], 18: [(1, 13), (1, 15), (1, 17), (1, 19)], 19: [(1, 15), (1, 18), (1, 20)], 20: [(1, 16), (1, 19)]})"""def dijkstra_raw(edges, from_node, to_node):g = defaultdict(list)#使用list作第一個(gè)參數(shù),可以很容易將鍵-值對(duì)序列轉(zhuǎn)換為列表字典。for l, r, c in edges:g[l].append((c, r))q, seen = [(0, from_node, ())], set()#q=[(0, from_node, ())],q為當(dāng)前節(jié)點(diǎn)創(chuàng)建一個(gè)堆while q:(cost, v1, path) = heappop(q)#刪除q中的頂if v1 not in seen:#如果V1沒(méi)有被查看,V1為出發(fā)點(diǎn)seen.add(v1)#將V1添加進(jìn)已查看path = (v1, path)#(點(diǎn),路徑)if v1 == to_node:#如果當(dāng)前點(diǎn)是目標(biāo)點(diǎn)return cost, path#返回距離和路徑for c, v2 in g.get(v1, ()):#遍歷V1的所有鄰居 c為到鄰居的距離,V2為鄰居if v2 not in seen:heappush(q, (cost + c, v2, path))#修改起點(diǎn)到V2的距離return float("inf"), []

    全部代碼

    """ 一.定義圖 """ # ====================給一個(gè)所有節(jié)點(diǎn)的列表 list_nodes_id = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; ### ==================== 給一個(gè)拓?fù)涞某?shù)矩陣. fin= float('inf') # 無(wú)窮大。這意味著沒(méi)有聯(lián)系。 #fin_topo是表示拓?fù)涞亩S鄰接矩陣 fin_topo = [[fin, 2.9, 2.5, fin, 2, fin, 1.8, 3, 1.8, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 0[2.9, fin, 1.3, fin, fin, 1.7, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 1[1, 1, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 2[fin, fin, 1, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 3[1, fin, fin, 1, fin, fin, fin, fin, fin, 1, 1, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 4[fin, 1, fin, fin, fin, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 5[1, fin, fin, fin, fin, 1, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 6[1, fin, fin, fin, fin, fin, 1, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 7[1, fin, fin, fin, fin, fin, fin, 1, fin, 1, fin, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin], # 8[fin, fin, fin, fin, 1, fin, fin, fin, 1, fin, fin, 1, fin, fin, fin, fin, fin, fin, fin, fin, fin], # 9[fin, fin, fin, fin, 1, fin, fin, fin, fin, fin, fin, 1, fin, 1, fin, fin, fin, fin, fin, fin, fin], # 10[fin, fin, fin, fin, 1, fin, fin, fin, fin, 1, 1, fin, fin, 1, 1, fin, fin, fin, fin, fin, fin], # 11[fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, fin, fin, fin, fin, 1, fin, fin, fin, fin, fin, fin], # 12[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, 1, fin, fin, 1, fin, fin, 1, 1, fin, fin], # 13[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, 1, 1, fin, 1, 1, fin, fin, fin, fin], # 14[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, 1, fin, 1, 1, fin], # 15[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, 1, fin, fin, fin, fin, 1], # 16[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, fin, fin, fin, 1, fin, fin], # 17[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, 1, fin, 1, fin, 1, fin], # 18[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, fin, 1, fin, 1], # 19[fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, fin, 1, fin, fin, 1, fin], # 20 ]#--- 讀取拓?fù)?#xff0c;并生成給定拓?fù)渲械乃羞叀?/span> edges = [] for i in range(len(fin_topo)):for j in range(len(fin_topo[0])):if i != j and fin_topo[i][j] != fin:edges.append((i, j, fin_topo[i][j])) ### (i,j) 是一個(gè)鏈接;fin_topo[i][j]這里是1,鏈接的長(zhǎng)度(i,j). #print(edges) #[(0, 1, 2.9), (0, 2, 2.5), (0, 4, 2), (0, 6, 1.8), (#算法實(shí)現(xiàn) from collections import defaultdict from heapq import *def dijkstra_raw(edges, from_node, to_node):g = defaultdict(list)#使用list作第一個(gè)參數(shù),可以很容易將鍵-值對(duì)序列轉(zhuǎn)換為列表字典。for l, r, c in edges:g[l].append((c, r))q, seen = [(0, from_node, ())], set()#q=[(0, from_node, ())],q為當(dāng)前節(jié)點(diǎn)創(chuàng)建一個(gè)堆while q:(cost, v1, path) = heappop(q)#刪除q中的頂if v1 not in seen:#如果V1沒(méi)有被查看,V1為出發(fā)點(diǎn)seen.add(v1)#將V1添加進(jìn)已查看path = (v1, path)#(點(diǎn),路徑)if v1 == to_node:#如果當(dāng)前點(diǎn)是目標(biāo)點(diǎn)return cost, path#返回距離和路徑for c, v2 in g.get(v1, ()):#遍歷V1的所有鄰居 c為到鄰居的距離,V2為鄰居if v2 not in seen:heappush(q, (cost + c, v2, path))return float("inf"), []start = int(input("請(qǐng)輸入起始點(diǎn):")) end = int(input("請(qǐng)輸入終點(diǎn):")) print("=== Dijkstra算法 ===") print("找從 %s 到 %s的最短路徑:" % (start, end)) length, path_queue = dijkstra_raw(edges,start, end)#path_queue路徑 print('距離',length) print('路徑',path_queue)

    0到15的距離為4.8,路徑0-8-12-14-15

    工具包講解

    參考我以前的博文
    最短路徑Dijkstra講解,工具包使用 python

    作者:電氣-余登武

    總結(jié)

    以上是生活随笔為你收集整理的用图讲解狄克斯特拉(DiskStra)算法,python实现 。的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。