單源最短路徑(Dijkstra)——貪心演算法

來源:互聯網
上載者:User

標籤:blog   http   os   io   for   2014   ar   問題   

    Dijkstra演算法是解單源最短路徑問題的貪心演算法。其基本思想是,設定頂點集合點集合S並不斷地做貪心選擇來擴充這個集合。一個頂點屬於集合S若且唯若從源到該頂點的最短路徑長度已知。初始時,S中僅含有源。設u是G的其一頂點。把從源到u且中間只經過S中頂點的路稱為從源到u的特殊路徑,並用數組Distance記錄當前每個頂點所對應的最短特殊路徑長度。Dijkstra演算法每次從V-S中取出具有最短特殊路長度的頂占,Distance就記錄了從源到所有其它頂點之間最短路徑長度。
    例如中的有向圖,應用Dijkstra演算法計算從源頂點1到其它頂點最短路徑的過程列表在下表中。


演算法流程說明:
    表格中預設選取的起始頂點為1頂點,所以本問題就轉化為求解1頂點到2, 3, 4, 5這幾個頂點的最短路徑。首先初始條件列出1頂點到2, 3, 4, 5各個頂點的距離,這個距離直接在圖的儲存鄰接矩陣中得到,選取距離最近的一個也就是2頂點加入集合S,下面要進行的是比較關鍵的一步,這個時候應該去擷取3, 4, 5三個頂點到集合S的最短距離(從1頂點出發,可以經過S中的任意頂點):將1到2頂點的距離加上2到各個點的距離,然後用這個距離來同1到各個頂點的距離相比較,誰小就取誰,以此類推,然後每次取Distance[]最小的值進入集合S。
    這樣下去,Distance[]中存放的就是每個頂點到集合S的最短距離,比如當前的集合只有1, 2,按照規則頂點4應該入選進集合S,因為Distance[3]沒有入選集合的頂點中對應的Distance[]最小的頂點。現在需要計算3和5到新集合S={1, 2, 4}的最短距離,這個時候就只需要將Distance[2]和Distance[4]中的值(現在這裡面的值表示集合S={1, 2}到頂點3和5頂點的最短距離),但是現在集合中加入了頂點4,怎麼計算?計算方法如下:
Distance[3] + 鄰接矩陣中頂點4到頂點3的距離 < Distance[2] ?
Distance[3]:(頂點4到S={1, 2}的最短距離)
Distance[2]: (頂點3到S={1, 2}的最短距離)
如果這個小於成立,那麼很明顯新的集合到頂點3的最小距離應該是先從S={1, 2}到頂點4的最短距離,然後再從頂點4到頂點3。

由於每一次的比較都是在上一次集合的最優結果中計算的,所以新計算出來的頂點3到集合S={1, 2, 4}的最短距離也是全域最優的。

對應的C語言代碼如下:

#include <stdio.h>#define M65535 //無窮大#define N5 //頂點數//Dijkstra演算法函數,求給定頂點到其餘各點的最短路徑//參數:鄰接矩陣、出發點的下標、結果數組、路徑前一點記錄void Dijkstra(int Cost[][N], int v0, int Distance[], int prev[]){    int s[N];    int mindis,dis;    int i, j, u;    //初始化    for(i=0; i<N; i++)    {        Distance[i] = Cost[v0][i];        s[i] = 0;        if(Distance[i] == M)prev[i] = -1;        elseprev[i] = v0;    }    Distance[v0] = 0;    s[v0] = 1; //標記v0    //在當前還未找到最短路徑的頂點中,    //尋找具有最短距離的頂點    for(i=1; i < N; i++)    {//每迴圈一次,求得一個最短路徑        mindis = M;        u = v0;        for (j=0; j < N; j++) //求離出發點最近的頂點if(s[j]==0 && Distance[j]<mindis){mindis = Distance [j];u = j;} // if語句體結束,j迴圈結束        s[u] = 1;        for(j=0; j<N; j++) //修改遞增路徑序列(集合)        if(s[j]==0 && Cost[u][j]<M)        { //對還未求得最短路徑的頂點            //求出由最近的頂點 直達各頂點的距離            dis = Distance[u] +Cost[u][j];            // 如果新的路徑更短,就替換掉原路徑            if(Distance[j] > dis)            {                Distance[j] = dis;                prev[j] = u;            }        } // if 語句體結束,j迴圈結束    } // i迴圈結束}// 輸出最短路徑// 參數:路徑前一點記錄、出發點的下標、到達點下標void PrintPrev(int prev[],int v0,int vn){    int tmp = vn;    int i, j;    //臨時存路徑    int tmpprv[N];    //初始化數組    for(i=0; i < N; i++)tmpprv[i] = 0;    //記錄到達點下標    tmpprv[0] = vn+1;    //中間點用迴圈記錄    for(i =0, j=1; j < N ;j++)    {        if(prev[tmp]!=-1 && tmp!=0)        {            tmpprv[i] = prev[tmp]+1;            tmp = prev[tmp];            i++;        }        else break;    }    //輸出路徑,數組逆向輸出    for(i=N-1; i >= 0; i--)    {        if(tmpprv[i] != 0)        { //排除0元素            printf("V%d", tmpprv[i]);            if(i)  //不是最後一個輸出符號                 printf("-->");        }    }printf("-->V%d", vn+1);}//主函數int main(){    //給出有向網的頂點數組    char *Vertex[N]={"V1", "V2", "V3", "V4", "V5"};    //給出有向網的鄰接矩陣    int Cost[N][N]={{0, 10, M, 30, 100},        {M, 0, 50, M, M},        {M, M, 0, M, 10},        {M, M, 20, 0, 60},        {M, M, M, M, 0},    };    int Distance[N]; //存放求得的最短路徑長度    int prev[N];  //存放求得的最短路徑int i;    //調用Dijkstra演算法函數,求頂點V1到其餘各點的最短路徑    //參數:鄰接矩陣、頂點數、出發點的下標、 結果數組    Dijkstra(Cost, 0, Distance, prev);    for(i=0; i < N; i++)    {        //輸出最短路徑長度        printf("%s-->%s:%d\t", Vertex[0], Vertex[i], Distance[i]);        //輸出最短路徑        PrintPrev(prev, 0, i);        printf("\n");    }    return 0;}
程式運行結果:


參考文章:http://zengwu3915.blog.163.com/blog/static/278348972009109101834282/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.