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

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

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

07-狄克斯特拉算法

發(fā)布時(shí)間:2023/12/4 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 07-狄克斯特拉算法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

數(shù)據(jù)結(jié)構(gòu)和算法
基于《算法圖解》—Aditya Bhargava 和《數(shù)據(jù)結(jié)構(gòu)》—嚴(yán)蔚敏

第7章 狄克斯特拉算法

上一章的廣度優(yōu)先搜索,找出的是段數(shù)最少的路徑;
本章狄克斯特拉算法,找出的是最快的路徑。

7.1 使用狄克斯特拉算法
步驟:
第一步:找出最便宜的節(jié)點(diǎn)

從起點(diǎn)出發(fā),前往節(jié)點(diǎn)A需要6分鐘,而前往節(jié)點(diǎn)B需要2分鐘。置于前往其他節(jié)點(diǎn),先假設(shè)為不窮大。

第二步:計(jì)算經(jīng)節(jié)點(diǎn)B前往其各個(gè)鄰居所需的時(shí)間。

經(jīng)節(jié)點(diǎn)B可以找到前往節(jié)點(diǎn)A更短的路徑,只需要5分鐘。

對(duì)于節(jié)點(diǎn)B的鄰居,如果找到前往它的更短路徑,就更新其開(kāi)銷:

  • 前往節(jié)點(diǎn)A的更短路徑(從6分鐘縮短到5分鐘)。
  • 前往終點(diǎn)的更短路徑(從無(wú)窮大縮短到7分鐘)。

第三步:重復(fù)

重復(fù)第一步:找出可能在最短時(shí)間內(nèi)前往的節(jié)點(diǎn)。 已經(jīng)對(duì)節(jié)點(diǎn)B執(zhí)行了第二步,除節(jié)點(diǎn)B外,可在最短時(shí)間內(nèi)前往的節(jié)點(diǎn)是節(jié)點(diǎn)A。

重復(fù)第二步:更新節(jié)點(diǎn)A的所有鄰居節(jié)點(diǎn)開(kāi)銷。

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

7.1.1
使用廣度優(yōu)先搜索來(lái)查找兩點(diǎn)之間的最短路徑,指的是段數(shù)最少;
而在狄克斯特拉算法中,每段都分配了一個(gè)數(shù)字或權(quán)重,因此找出的是總權(quán)重最小的路徑。

狄克斯特拉算法的4個(gè)步驟:

  • (1)找出最便宜的節(jié)點(diǎn),即可在最短時(shí)間內(nèi)前往的節(jié)點(diǎn)。
  • (2)對(duì)于該節(jié)點(diǎn)的鄰居,檢查是否有前往它們的更短路徑,如果有,就更新其開(kāi)銷。
  • (3)重復(fù)這個(gè)過(guò)程,直到對(duì)圖中的每個(gè)節(jié)點(diǎn)都這樣做了。
  • (4)計(jì)算最終路徑。

7.2 術(shù)語(yǔ)

  • 狄克斯特拉算法用于每條邊都有關(guān)聯(lián)數(shù)字的圖,這些數(shù)字稱為權(quán)重(weight)。
  • 帶權(quán)重的圖為加權(quán)圖(weighted graph),不帶權(quán)重的圖為非加權(quán)圖(unweight graph)。
  • 環(huán):從一個(gè)節(jié)點(diǎn)出發(fā),走一圈后又回到這個(gè)節(jié)點(diǎn)。繞環(huán)的路徑不可能是最短路徑。
  • 無(wú)向圖意味著兩個(gè)節(jié)點(diǎn)彼此指向?qū)Ψ?#xff0c;其實(shí)就是環(huán)。在無(wú)向圖中,每條邊都是一個(gè)環(huán)。
  • 狄克斯特拉算法只適用于有向無(wú)環(huán)圖(directed acyclic graph,DAG)。

7.3 換鋼琴例子
Rama想用自己的樂(lè)譜來(lái)?yè)Q架鋼琴,那么需要確定哪種路徑將樂(lè)譜換成鋼琴時(shí)需要支付的額外費(fèi)用最少。

使用狄克斯特拉算法可得到:

7.4 負(fù)權(quán)邊
如果有負(fù)權(quán)邊,就不能使用狄克斯特拉算法。
因?yàn)榈铱怂固乩惴ㄊ沁@樣假設(shè)的:對(duì)于處理過(guò)的海報(bào)節(jié)點(diǎn),沒(méi)有前往該節(jié)點(diǎn)的更短路徑。這種假設(shè)僅在沒(méi)有負(fù)權(quán)邊時(shí)才成立。
在包含負(fù)權(quán)邊的圖中,要找出最短路徑,可使用貝爾曼-福德算法。

7.5 實(shí)現(xiàn)
以下圖為例。

要編寫(xiě)解決這個(gè)問(wèn)題的代碼,需要三個(gè)散列表。

算法實(shí)現(xiàn)思路

#實(shí)現(xiàn)圖GRAPH:將節(jié)點(diǎn)的鄰居和前往鄰居的開(kāi)銷存儲(chǔ)到散列表中。 graph["start"] = {} graph["start"]["a"] = 6 graph["start"]["b"] = 2graph["a"] = {} graph["a"]["fin"] = 1 #fin指到終點(diǎn)graph["b"] = {} graph["b"]["a"] = 3 graph["b"]["fin"] = 5graph["fin"] = {} #終點(diǎn)沒(méi)有任何鄰居#實(shí)現(xiàn)圖COSTS:節(jié)點(diǎn)的開(kāi)銷指的是從節(jié)點(diǎn)出發(fā)前往該節(jié)點(diǎn)需要多長(zhǎng)時(shí)間。 infinity = float("inf") costs = {} costs["a"] = 6 costs["b"] = 2 costs["fin"] = infinity#實(shí)現(xiàn)圖PARENTS:存儲(chǔ)父節(jié)點(diǎn)的散列表。 parents = {} parents["a"] = "start" parents["b"] = "start" parents["fin"] = None processed = [] #記錄處理過(guò)的幾點(diǎn)的數(shù)組,避免多次處理。

準(zhǔn)備工作做好了,接下來(lái)實(shí)現(xiàn)算法。
圖4.2

#首先定義函數(shù)find_lowest_cost_node找出開(kāi)銷最低的結(jié)點(diǎn) def find_lowest_cost_node(costs):lowest_cost = float("inf")lowest_cost_node = Nonefor node in costs: #遍歷所有節(jié)點(diǎn)cost = costs[node]if cost < lowest_cost and node not in processed: #如多當(dāng)前節(jié)點(diǎn)的開(kāi)銷更低且未處理過(guò),lowest_cost = cost #就將其視為開(kāi)銷最低的節(jié)點(diǎn)lowest_cost_node nodereturn lowest_cost_node#實(shí)現(xiàn)狄克斯特拉算法 node = find_lowest_cost_node(costs) #在未處理的節(jié)點(diǎn)中找出開(kāi)銷最小的節(jié)點(diǎn)。 while node is not None: #這個(gè)while循環(huán)在所有節(jié)點(diǎn)都被處理過(guò)后結(jié)束cost = cost[node]neighbors = graph[node]for n in neighbors.key(s): #遍歷當(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 #就更新該鄰居的開(kāi)銷parents[n] = node #同時(shí)將該鄰居的父節(jié)點(diǎn)設(shè)置為當(dāng)前節(jié)點(diǎn)processed.append(node) #將當(dāng)前節(jié)點(diǎn)標(biāo)記為處理過(guò)node = find_lowest_cost_node(costs) #找出接下來(lái)要處理的節(jié)點(diǎn),并循環(huán)

7.6 小結(jié)

  • 廣度優(yōu)先搜索用于在非加權(quán)圖中查找最短路徑。
  • 狄克斯特拉算法用于在加權(quán)圖中查找最短路徑。
  • 僅當(dāng)權(quán)重為正時(shí)狄克斯特拉算法才管用。
  • 如果圖中包含負(fù)權(quán)邊,請(qǐng)使用貝爾曼-福德算法。

——持續(xù)修改完善中…

總結(jié)

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

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