1. 程式人生 > >最短路徑之Dijkstra(迪傑斯特拉)演算法(無向圖)

最短路徑之Dijkstra(迪傑斯特拉)演算法(無向圖)

簡介

Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。由for迴圈可知,其時間複雜度是O(n^2)。

原理

      在已知圖的鄰接矩陣net.vexs[i][j](無向網,含權值的圖)的條件下,過遍歷已知圖的所有路徑,用dis[i]陣列來記錄到i點的最短路徑,然後在迴圈中不斷判斷更替。首先,將所有點的集合分為倆部分,一邊是已經遍歷過的,另外一邊是沒有遍歷過的,分別用mark[i]=1、mark[i]=0來表示。

程式碼通解

 在下面程式碼中,先將賦予初始值dis[i]=INF(無窮大)、mark[i]=0(未標記),而後單獨將源點(x)所聯通的路徑權值net.arcs[x][i]

賦予dis[i](<INF稱為初始化),i為聯通的點,暫定為到i的最短路徑,標記mark[x]=1,即已經遍歷;然後,在一個for遍歷了所有節點的大迴圈裡面:

                                                          ①尋找遍歷到點聯通路徑(與之相連線的點)中權值最小的一條; 標記遍歷點;

                                                          ②修正最短路徑;

而後,便是已經遍歷所有點了,dis[i]也在不斷的修正中得到真正的最小值,即最短路徑。詳情看下列程式碼

void Dijkstra(int x,int y)      // x為源點,y為終點
{
    int i,j,k;
    int min;
    int u;   //下一個放入集合p的點
    int dis[net.vexnum];   //  最短路徑
    int mark[net.vexnum];   //   被mark的便是已經遍歷,未被mark的便是未遍歷
    /*首先進行最短路徑初始化*/
    for(i=0; i<net.vexnum; i++)
    {
        mark[i] = 0;
        dis[i] = net.arcs[x][i];
    }


    mark[x]=1;          // 標記源點
    
    
    for(k=0; k<net.vexnum; k++)          // for 大迴圈
    {
        min = INF;   //  min初始化最大值,便於後來資料替換(每一個點的出度入度判斷)
        
        /*尋找遍歷到點聯通路徑(與之相連線的點)中權值最小的一條; 標記遍歷點;*/
        for(i=0; i<net.vexnum; i++)
        {
            if(mark[i]==0&&min>dis[i])      //判斷未遍歷點 且 被賦值的最短路徑(dis[i]<INF),未被賦值的點     //                                                     應當min==dis[i]=INF
            {
               min = dis[i];             //在已知賦值最短路徑中,尋找權值最小的點並將他作為下一個遍歷 
               u=i;                            //點u點
            }
        }


        mark[u]=1;      //標記u點
 
        /*修正最短路徑*/
        for(i=0;i<net.vexnum;i++)
        {
            if(!mark[i]&&dis[i]>dis[u]+net.arcs[u][i])                 // !mark[i]判斷不去走回頭路,         //                                                                                dis[i]>dis[u]+net.arcs[u][i]有倆個用途:①若u連結的是x源點沒有賦值最短路徑的點,那麼這裡可以賦值②若是賦值過的點,那麼可以判斷是上一個dis[i](此時是被賦值過的)是不是真正的最短路徑,即修正。

            {
                dis[i] = dis[u] + net.arcs[u][i];      //若A->C比A->B->C更長那麼A->B->C則是到C的最短路徑,下圖將解釋。
         
                   }
             }
    }
     printf("最短路徑值為:             %d",dis[y]);
}


我們以A,B,C三個點來舉例子,三個點的最短路徑分別為dis[0]、dis[1]、dis[2]。

                                                   ①A為源點初始化,dis[B]=3 (到B的最短路徑,dis[1]),  dis[C]=6;

②dis[B]<dis[C],選取B為u下一個遍歷點;與B相聯的有A(不走回頭路)、E、C;

                                                   ③E未賦值,賦予dis[E];  C被之前賦予過,比較  dis[C] > dis[B] + net.arcs[B][C] (要不然你根本進不了這兒),重新賦值dis[C] = dis[B]+net.arcs[B][C];

                                                   ④大迴圈遍歷所有點,走遍天下。




我覺得下面幾張圖很不錯,圖片取自https://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html




相關推薦

路徑Dijkstra()演算法

簡介 Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。由for迴圈可知,其

演算法處理路徑的(dijkstra)Java實現(指定兩點,求短距離及路徑)

其實不是原創哈,我寫不出來。       如何求圖中V0到V5的最短路徑呢?         java實現的方式如下:         第一步,根據圖來建立權值矩陣:        int[][] W = {      {  0,   1,   4,  -1,  -

路徑算法——Dijkstra

graph 就是 print 偽代碼 c語言程序 距離 oid 很大的 全部 算法思想 設G=(V,E)是一個帶權有向圖 把圖中頂點集合V分成兩組 第一組為已求出最短路徑的頂點集合(用S表示,初始時S中只有一個源點,以後每求得一條最短路徑 , 就將加入到集合S中,直到全部

資料結構路徑Dijkstra()演算法

1)常用的圖最短路徑的演算法有兩個:Dijkstra演算法和Floyd演算法; 2)Dijkstra演算法適用於求圖中兩節點之間最短路徑,Floyd演算法適於求圖中任意兩節點間; 3)兩種演算法的主要思想是動態規劃,而Dijkstra演算法設計比較巧妙的是:在求源節點到終結

路徑-Dijkstra()演算法

最短路徑-Dijkstra(迪傑斯特拉)演算法 網圖的最短路: 最短路徑,是指兩頂點之間經過的邊上權值之和最小的路徑,並且我們稱路徑的第一個頂點是源點,最後一個頂點是終點 Dijkstra(迪傑斯特拉)演算法: 概況: 按路徑長度

圖解-演算法路徑Dijkstra's Algorithm (finding shortestpaths)

轉自:http://www.mathcs.emory.edu/~cheung/Courses/171/Syllabus/11-Graph/dijkstra2.html   一. 圖解迪傑斯特拉   Before showing you the&nb

路徑演算法1Dijkstra()演算法

Dijkstra(迪傑斯特拉)演算法是典型的最短路徑路由演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。Dijkstra演算法能得出最短路徑的最優解,但由於它遍歷計算的節點很多,所以效率

Dijkstra []演算法思路求單點到其他每個點的各個路徑Floyd演算法:任意兩點間短距離

先給出一個無向圖 用Dijkstra演算法(迪傑斯特拉演算法)找出以A為起點的單源最短路徑步驟如下 應用Dijkstra演算法計算從源頂點1到其它頂點間最短路徑的過程列在下表中。 Dijkstra演算法的迭代過程: Floyd演算法思想: 1、從任意一條單邊路徑開

路徑演算法Dijkstra()演算法分析與實現(Python)

December 18, 2015 12:56 PM Dijkstra(迪傑斯特拉)演算法是典型的最短路徑演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。Dijkstra演算法能得出最短路徑的

路徑演算法Dijkstra()演算法分析與實現(C/C++)

Dijkstra(迪傑斯特拉)演算法是典型的最短路徑路由演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。Dijkstra演算法能得出最短路徑的最優解,但由於它遍歷計算的節點很多,所以效率低。   Dijks

路徑演算法Dijkstra()演算法分析與實現(C/C++)及其他 + leetcode習題實踐

   最短路徑求解  最短路徑的常用解法有迪傑克斯特拉演算法Dijkstra Algorithm, 弗洛伊德演算法Floyd-Warshall Algorithm, 和貝爾曼福特演算法Bellman-Ford Algorithm,其中,Floyd演算法是多源最短路徑,即求

演算法可列印路徑資料結構題集C語言版7.11

轉自 https://blog.csdn.net/cxllyg/article/details/7604812   #include <iostream> #include <iomanip> #include <string> usi

資料結構--C語言--的深度優先遍歷,廣度優先遍歷,拓撲排序,用prime演算法實現小生成樹,用演算法實現關鍵路徑和關鍵活動的求解,路徑

實驗七  圖的深度優先遍歷(選做,驗證性實驗,4學時) 實驗目的 熟悉圖的陣列表示法和鄰接表儲存結構,掌握構造有向圖、無向圖的演算法 ,在掌握以上知識的基礎上,熟悉圖的深度優先遍歷演算法,並實現。 實驗內容 (1)圖的陣列表示法定義及

路徑演算法:克魯卡爾演算法演算法天勤資料結構高分筆記

迪傑斯特拉演算法演算法思想:     設有兩個頂點集合S和T,集合S存放途中已經找到最短路徑的頂點,集合T存放的是途中剩餘頂點。初始狀態是,集合S只包含源點V0,然後不斷從集合T中     選取到頂點V0的路徑長度最短的頂點Vu併入到初始集合中。集合S每併入一個新的頂點Vu,

短路 演算法鄰接矩陣

理解了好幾天的最短路,今天有點眉目了 在每年的校賽裡,所有進入決賽的同學都會獲得一件很漂亮的t-shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎? Input

演算法Dijkstra algorithm

       emmmm....寫語氣詞被同桌吐槽啊....嫌我emmm太長。桑心QAQ        好把同桌趕跑了~        這次來講迪傑斯特拉,這個東西嘛...和我們上一次看的弗洛伊德差不多啦,對沒錯不是那個寫性學三論的傢伙,所以不用期待我的文章裡會出現什麼奇

Dijkstra 演算法詳細步驟及實現

1,迪傑斯特拉演算法介紹 迪傑斯特拉演算法是典型最短路徑演算法,用於計算圖或網中某個特定頂點到其他所有頂點的最短路徑。主要特點是以起始點為中心向外,層層擴充套件,直到擴充套件覆蓋所有頂點。 2,迪傑斯特拉演算法思想 設G=(V,E)為一個帶全有向圖,把圖中頂點集合

dijkstra演算法

在圖的應用中,有一個很重要的需求:我們需要知道從某一個點開始,到其他所有點的最短路徑。    這其中,Dijkstra演算法是典型的最短路徑演算法。它的關鍵思想是以起始點為中心,向外一層層擴散,直到擴充套件到終點為止。Dijkstra演算法能夠得出最短路徑的最優解,不過

筆記:路徑算法—Dijkstra()

意思 最終 else min out 拓展 clas stream 便是 文中代碼下如下: #include<iostream> #include<cstdio> #include<fstream> #include<algor

路徑問題dijkstra演算法

題目描述 給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。 輸入描述: 輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其