最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Dijkstra算法詳細(xì)介紹及Python實現(xiàn)方法

 更新時間:2026年03月20日 09:23:54   作者:不去幼兒園  
迪杰斯特拉(Dijkstra)算法是一種用于尋找有向圖中單源最短路徑的經(jīng)典算法,在這個算法中,我們從一個源節(jié)點開始,逐步擴展最短路徑到其他節(jié)點,直到到達(dá)所有節(jié)點或者目標(biāo)節(jié)點,這篇文章主要介紹了Dijkstra算法詳細(xì)介紹及Python實現(xiàn)的相關(guān)資料,需要的朋友可以參考下

1. Dijkstra算法介紹

Dijkstra算法,全稱迪杰斯特拉算法,是由荷蘭計算機科學(xué)家艾茲赫爾·戴克斯特拉(Edsger W. Dijkstra)在1956年提出的,是一種用于解決圖中的最短路徑問題的算法。這種算法適用于帶權(quán)重的圖,其中每條邊有一個非負(fù)的權(quán)重值。

這篇論文發(fā)表于1959年的《Numerische Mathematik》期刊第1期,第269-271頁,《A Note on Two Problems in Connexion with Graphs》。在這篇論文中,他不僅描述了這個算法,還提供了第一次正式的最短路徑問題算法理論證明。這篇論文的題目雖然翻譯成中文是《關(guān)于與圖相關(guān)的兩個問題的說明》,但它在算法史上有著非常重要的地位,因為其中描述的Dijkstra算法成為了解決圖中最短路徑問題的基石。

2.文獻(xiàn)閱讀

《A Note on Two Problems in Connexion with Graphs》的核心內(nèi)容主要針對兩個問題:

問題1:構(gòu)造n個節(jié)點間總長度最小的樹(最小生成樹)

  • 基本思路:將邊分為3個集合(確定屬于生成樹的邊的集合I、待選邊集合II、剩余邊集合III),將節(jié)點分為2個集合(已連接集合A、剩余節(jié)點集合B)。初始時,任選一節(jié)點作為集合A的唯一成員,所有以此節(jié)點為終點的邊放入集合II,集合I為空。

  • 構(gòu)造步驟

    • 步驟1:從集合II中選出最短的邊,將其移出集合II并加入集合I,同時將對應(yīng)的節(jié)點從集合B轉(zhuǎn)移到集合A。

    • 步驟2:考慮剛轉(zhuǎn)移到集合A的節(jié)點與集合B中節(jié)點相連的邊,若邊長比集合II中對應(yīng)邊長則被舍棄,若更短則替換集合II中的對應(yīng)邊并舍棄后者。然后返回步驟1重復(fù)此過程,直到集合II和III均為空,此時集合I中的邊即構(gòu)成所需的最小生成樹。

  • 優(yōu)勢:相較于J.B. KRUSKAL、H. LOBERMAN和A. WEINBERGER的方法,該方法無需預(yù)先所有對邊按長度排序,且只需同時存儲最多n條邊的數(shù)據(jù)(集合I和II中的邊以及步驟2中考慮的邊),而其他方法即使邊的長度是節(jié)點坐標(biāo)的可計算函數(shù),也需要同時存儲所有邊的數(shù)據(jù)。

問題2:尋找給定兩點P和Q間總長度最小的路徑

  • 基本思路:利用若R是P到Q的最小路徑上的節(jié)點,則知道P到Q的最小路徑也就知道P到R的最小路徑這一事實。在解決方案中,按路徑長度遞增的順序構(gòu)造P到其他節(jié)點的最小路徑,直到到達(dá)Q。

  • 具體步驟

    • 初始狀態(tài):所有節(jié)點在集合C,所有邊在集合III。將節(jié)點P轉(zhuǎn)移到集合A,然后反復(fù)執(zhí)行以下步驟。

    • 步驟1:考慮連接剛轉(zhuǎn)移到集合A的節(jié)點與集合B或C中的節(jié)點R的所有邊r。若R屬于集合B,判斷使用邊r是否能獲得比已知路徑更短的P到R的路徑,若不能則邊r被舍棄,若能則替換集合II中的對應(yīng)邊并舍棄后者;若R屬于集合C,則將R加入集合B并將邊r加入集合II。

    • 步驟2:集合B中的每個節(jié)點通過集合I中的一條邊和集合II中的一條邊與節(jié)點P相連,每個節(jié)點B都有一個到P的距離。將集合B中到P距離最小的節(jié)點轉(zhuǎn)移到集合A,對應(yīng)的邊從集合II轉(zhuǎn)移到集合I。然后返回步驟1重復(fù)此過程,直到節(jié)點Q被轉(zhuǎn)移到集合A,此時即找到解決方案。

  • 優(yōu)勢:與L. R. FORD的方法相比,無論邊的數(shù)量如何,該方法無需同時存儲所有邊的數(shù)據(jù),只需存儲集合I和II中的邊,且這個數(shù)量總是小于n,同時所需的工作量也明顯更少。

總結(jié)

該論文主要介紹了兩種解決圖論問題的方法,分別針對構(gòu)造最小生成樹和尋找兩點間最短路徑。這兩種方法在數(shù)據(jù)存儲和計算工作量方面相較于其他方法具有優(yōu)勢,能夠更高效地解決相應(yīng)的問題。

《A Note on Two Problems in Connexion with Graphs》中沒有直接提及“Dijkstra算法”這個名稱。但其中提出的解決最短路徑問題的方法后來被廣泛稱為Dijkstra算法。文件中針對最短路徑問題所描述的解決方法,其核心思路與Dijkstra算法完全一致,即通過維護節(jié)點集合和邊集合的特定方式,逐步確定從起點到其他節(jié)點的最短路徑。

2.Dijkstra算法原理

想象一下,你在一座迷宮里,你想要從起點A到達(dá)終點B并找到最短的路徑,那么你可以使用Dijkstra算法。這個算法會幫助你計算出從起點到所有其他點的最短距離,并且最終告訴你到達(dá)終點B的最短路徑是什么。

核心思想:

  1. 初始化:從一個頂點開始(我們稱之為源點),將源點到自身的距離設(shè)為0,而到其他頂點的距離設(shè)為無窮大。
  2. 選擇最近頂點:在所有未被訪問過的頂點中,選擇距離源點最近的一個頂點(稱之為當(dāng)前頂點)。
  3. 更新距離:檢查通過當(dāng)前頂點可以到達(dá)的所有其他未被訪問過的頂點,如果通過當(dāng)前頂點到達(dá)這些頂點的距離比之前已知的更短,就更新這些頂點的距離。
  4. 標(biāo)記已訪問:將當(dāng)前頂點標(biāo)記為已訪問,并從待訪問頂點集合中移除。
  5. 重復(fù)以上步驟:重復(fù)步驟2到4,直到所有的頂點都被訪問過或者目標(biāo)頂點被訪問。

示例:

假設(shè)我們有如下的圖中的四個節(jié)點和它們之間的邊及其權(quán)重:

  A---(2)---B
  |         |
(3)        (1)
  |         |
  ----------------C

我們要計算從A到C的最短路徑。

  1. 初始化:

    • A = 0, B = ∞, C = ∞
  2. 選擇最近的未訪問頂點B(因為它離A最近,距離為2)。

  3. 更新C的距離(因為B到C的距離是1,所以A到C的新距離是A到B的距離加上B到C的距離,即2+1=3):

    • A = 0, B = 2, C = 3
  4. 現(xiàn)在,B和C都是最近未訪問過的頂點,我們選擇B作為下一個當(dāng)前頂點(因為它先被檢查到)。

  5. 更新頂點后,沒有更短的路徑可以到達(dá)C了,我們將B標(biāo)記為已訪問。

  6. 現(xiàn)在C是唯一的未訪問頂點,我們選擇它作為當(dāng)前頂點。

  7. 最終結(jié)果是A到C的最短路徑是3。

推理公式:

Dijkstra算法沒有一個單一的公式,但是可以用偽代碼來說明它的邏輯:

function Dijkstra(Graph, source):
    dist[source] ← 0; // 初始化距離表
    for each vertex v in Graph: 
        if v ≠ source
            dist[v] ← ∞; 
            prev[v] ← undefined; // 前驅(qū)節(jié)點,用于記錄最短路徑
            Q ← all vertices in Graph; // 所有頂點的集合
    while Q is not empty:
        u ← vertex in Q with min dist[u];
        remove u from Q;
        for each neighbor v of u: // 遍歷u的所有鄰居v
            alt ← dist[u] + length(u, v);
            if alt < dist[v]:
                dist[v] ← alt;
                prev[v] ← u;
    return dist[];

這段偽代碼描述了Dijkstra算法的基本流程,其中dist[]存儲從源點到各個點的距離,prev[]用來存儲最短路徑樹,以便最后能回溯出最短路徑。

[Python] Dijkstra算法實現(xiàn)

下面給出一個簡單的Python實現(xiàn)Dijkstra算法的程序,以及一個示例圖和運行結(jié)果。這個程序會計算從源點到圖中所有其他節(jié)點的最短路徑,并輸出最短距離和路徑。

"""《Dijkstra算法程序》
    時間:2025.03.06
    作者:不去幼兒園
"""
import heapq

def dijkstra(graph, start):
    -distances = {vertex: float('infinity') for vertex in graph}
    distances[start] = 0
    -previous_nodes = {vertex: None for vertex in graph}
    -unvisited_queue = [(0, start)]

    while unvisited_queue:
        current_distance, current_vertex = heapq.heappop(unvisited_queue)

        if current_distance > distances[current_vertex]:
            continue

        for neighbor, weight in graph[current_vertex].items():
            distance = current_distance + weight

            if distance < distances[neighbor]:
                distances[neighbor] = distance
                previous_nodes[neighbor] = current_vertex
                heapq.heappush(unvisited_queue, (distance, neighbor))

    return distances, previous_nodes


# Example graph represented as an adjacency list
graph = {
    'A': {'B': 2, 'C': 3},
    'B': {'A': 2, 'C': 1, 'D': 4},
    'C': {'A': 3, 'B': 1, 'D': 5},
    'D': {'B': 4, 'C': 5}
}

start_vertex = 'A'
distances, previous_nodes = dijkstra(graph, start_vertex)

# Function to print the shortest path from start_vertex to end_vertex
def print_shortest_path(previous_nodes, start_vertex, end_vertex):
    path = []
    current_vertex = end_vertex
    while current_vertex is not None and current_vertex != start_vertex:
        path.insert(0, current_vertex)
        current_vertex = previous_nodes[current_vertex]
    if current_vertex is None:
        return "Path does not exist"
    else:
        path.insert(0, start_vertex)
        return path

# Output the results
print("Vertex\tDistance\tPath")
for vertex in graph:
    if vertex != start_vertex:
        dist = distances[vertex]
        path = print_shortest_path(previous_nodes, start_vertex, vertex)
        print(f"{vertex}\t{dist}\t\t{path}")

[Results] 運行結(jié)果

上述代碼中的例子圖,它展示了10個節(jié)點之間的連接關(guān)系和權(quán)重。圖形由頂點(A到J)和它們之間的邊與權(quán)重組成: 

    A
   /|\
  B C D
 / | \
E  F  |
 \ | /
  G H
   \ /
    I
    |
    J

每個節(jié)點與其直接相連的節(jié)點都有特定的權(quán)重。下面是這些連接關(guān)系和對應(yīng)的權(quán)重:

  • A 到 B: 2
  • A 到 C: 3
  • A 到 D: 1
  • B 到 C: 1
  • B 到 D: 4
  • B 到 E: 5
  • C 到 D: 1
  • C 到 E: 6
  • D 到 E: 2
  • E 到 F: 7
  • E 到 G: 9
  • F 到 G: 8
  • F 到 H: 5
  • G 到 H: 3
  • G 到 I: 6
  • H 到 I: 7
  • I 到 J: 2
Vertex    Distance    Path
B         2          ->A->B
C         3          ->A->C
D         1          ->A->D
E         3          ->A->D->E
F         6          ->A->D->E->F
G         10         ->A->D->E->G
H         8          ->A->D->E->F->H
I         11         ->A->D->E->F->H->I
J         13         ->A->D->E->F->H->I->J

3. Dijkstra算法的應(yīng)用場景

  1. 路徑規(guī)劃:Dijkstra算法常常被用于道路網(wǎng)絡(luò)中的最短路徑查找,它可以幫助導(dǎo)航系統(tǒng)提供從起點到目的地的最佳路線。

  2. 網(wǎng)絡(luò)路由選擇:在互聯(lián)網(wǎng)中,路由器可以使用Dijkstra算法來選擇數(shù)據(jù)傳輸?shù)淖罴崖窂健?/p>

  3. 社交網(wǎng)絡(luò)分析:分析人與人之間、組織之間的最短聯(lián)系路徑。

  4. 運輸和物流領(lǐng)域:尋找貨物從一個地點到另一個地點成本最低的運輸路徑。

  5. 電路設(shè)計:在集成電路布局中,Dijkstra算法可以用于尋找最小延遲路徑。

  6. 游戲設(shè)計:游戲中的NPC(非玩家角色)導(dǎo)航和尋路系統(tǒng)可能使用Dijkstra算法確定行動路徑。

  7. 電信網(wǎng)絡(luò):在電話網(wǎng)絡(luò)和其他電信網(wǎng)絡(luò)中定位呼叫的最佳路徑。

4.Dijkstra算法優(yōu)缺點

Dijkstra算法的優(yōu)點:

  1. 準(zhǔn)確性:Dijkstra算法總是能找到單源最短路徑的精確解,特別是當(dāng)所有邊的權(quán)重都是非負(fù)數(shù)時。

  2. 靈活性:在算法的執(zhí)行過程中如果找到從源點到目標(biāo)點的最短路徑,算法會立即停止處理該目標(biāo)點,這意味著你可以在任何時候中斷算法來查詢最短路徑。

  3. 適用于稠密圖:對于邊的數(shù)量接近于頂點數(shù)量平方的稠密圖,Dijkstra算法表現(xiàn)良好。

  4. 簡單性:算法的邏輯相對簡單,容易理解和實現(xiàn)。

  5. 可以優(yōu)先處理:通過優(yōu)先隊列的使用,Dijkstra算法可以快速訪問當(dāng)前最短路徑的節(jié)點。

Dijkstra算法的缺點:

  1. 效率問題:使用標(biāo)準(zhǔn)數(shù)組存儲距離信息時,時間復(fù)雜度為,其中V是頂點的數(shù)量。雖然通過使用斐波那契堆等優(yōu)化措施可以將時間復(fù)雜度降低到,但在最壞的情況下它仍然是效率較低的算法之一。

  2. 不適合負(fù)權(quán)重邊:Dijkstra算法不能用于包含負(fù)權(quán)邊的圖中,否則可能無法找到正確的最短路徑。

  3. 內(nèi)存消耗較大:需要存儲所有頂點的距離信息和已訪問狀態(tài),內(nèi)存使用隨著頂點數(shù)增加而增長。

  4. 對大規(guī)模圖不友好:當(dāng)圖變得非常大時,算法將消耗較長的時間計算最短路徑。

總結(jié)

到此這篇關(guān)于Dijkstra算法詳細(xì)介紹及Python實現(xiàn)方法的文章就介紹到這了,更多相關(guān)Python Dijkstra算法實現(xiàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python之sorted函數(shù)使用與實戰(zhàn)過程

    Python之sorted函數(shù)使用與實戰(zhàn)過程

    本文詳細(xì)介紹了Python中`sorted()`函數(shù)的用法,包括基礎(chǔ)語法、關(guān)鍵參數(shù)、復(fù)雜對象排序、多條件排序、性能與穩(wěn)定性以及實戰(zhàn)應(yīng)用場景,通過這些內(nèi)容,讀者可以掌握如何高效地對各種可迭代對象進(jìn)行排序
    2026-02-02
  • Flask如何獲取用戶的ip,查詢用戶的登錄次數(shù),并且封ip

    Flask如何獲取用戶的ip,查詢用戶的登錄次數(shù),并且封ip

    這篇文章主要介紹了Flask如何獲取用戶的ip,查詢用戶的登錄次數(shù),并且封ip問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Pygame的程序開始示例代碼

    Pygame的程序開始示例代碼

    這篇文章主要介紹了Pygame的程序開始的示例代碼,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • 詳解pytorch 0.4.0遷移指南

    詳解pytorch 0.4.0遷移指南

    這篇文章主要介紹了詳解pytorch 0.4.0遷移指南,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-06-06
  • Python數(shù)據(jù)庫格式化輸出文檔的思路與方法

    Python數(shù)據(jù)庫格式化輸出文檔的思路與方法

    這篇文章主要給大家介紹了關(guān)于Python數(shù)據(jù)庫格式化輸出文檔的思路與方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 在腳本中單獨使用django的ORM模型詳解

    在腳本中單獨使用django的ORM模型詳解

    這篇文章主要介紹了在腳本中單獨使用django的ORM模型詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • Python3標(biāo)準(zhǔn)庫之functools管理函數(shù)的工具詳解

    Python3標(biāo)準(zhǔn)庫之functools管理函數(shù)的工具詳解

    functools模塊提供的主要工具就是partial類,可以用來“包裝”一個有默認(rèn)參數(shù)的callable對象。這篇文章主要介紹了Python3標(biāo)準(zhǔn)庫functools管理函數(shù)的工具的實例詳解,需要的朋友可以參考下
    2020-02-02
  • 在python中對于bool布爾值的取反操作

    在python中對于bool布爾值的取反操作

    這篇文章主要介紹了在python中對于bool布爾值的取反操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Python3.7安裝PyQt5 運行配置Pycharm的詳細(xì)教程

    Python3.7安裝PyQt5 運行配置Pycharm的詳細(xì)教程

    這篇文章主要介紹了Python3.7成功安裝心得PyQt5 PyQt5-tools QT designer.exe運行配置Pycharm 將.ui文件翻譯成.py文件,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2020-10-10
  • python引入其他py文件或模塊

    python引入其他py文件或模塊

    本文主要介紹了python引入其他py文件或模塊,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01

最新評論

白银市| 西安市| 卢湾区| 蓝田县| 大余县| 合肥市| 南昌县| 黑河市| 榆社县| 沧州市| 宁陕县| 昆明市| 舒兰市| 安多县| 彭州市| 正镶白旗| 桦南县| 瑞金市| 三原县| 手游| 得荣县| 周宁县| 潜江市| 哈尔滨市| 新巴尔虎右旗| 洛宁县| 府谷县| 临安市| 东安县| 长寿区| 高邮市| 阜南县| 从化市| 涪陵区| 南雄市| 罗田县| 常德市| 西峡县| 祁连县| 江都市| 高唐县|