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

最短路徑之迪克斯特拉(Dijkstra)演算法

何謂最短路徑

顧名思義就是在一個圖中,一個頂點到另外一個頂點的最短距離拉。那麼這裡有一點要注意,就是在網圖中(邊的權值各不相同)最短路徑指的是倆點之間的連線權值最小;在非網圖(邊的權值都預設為1)中最短路徑指的是邊數最少的。

從一個頂點到其餘各頂點的最短路徑

採用迪克斯特拉演算法求解,基本思想是:
還是利用陣列來找出最短路徑,先迴圈遍歷出第一個頂點A離其他頂點的距離,然後儲存到一個數組裡,這時候數組裡對應的每一位就是各個頂點到A的距離。
找出距離最小的那個頂點B,重新計算B到其他頂點的距離,這裡有一點要說明一下:比如頂點C,他到頂點A的路徑可能經過B,又或者直接從A到C。這時候就需要A到B的距離加上B到C的距離之和與A到C的距離做比較,取出較小的那個儲存到陣列中。
那麼這樣說是簡單,通過程式碼怎麼實現呢?

//先進行初始化
//迴圈遍歷出第一個頂點A離其他頂點的距離,然後儲存到一個數組裡,這時候數組裡對應的每一位就是各個頂點到A的距離。
for(i=0;i<g.n;i++)
{
    dist[i]=g.edges[v][i];
    s[i] = 0;                //s[i]標誌著第i個頂點是否已經找到離某一點的最短路徑
    if(g.edges[v][i]<INF)
        path[i] = g.edges[v][i];//path陣列記錄第i個頂點的上一個頂點位置
    else
        path[i] = -1;       
}

關於s陣列和path陣列暫時不理解的可以看接下來的介紹。
接下來應該找出距離0頂點最近的那個點,就必須通過下面的程式碼:

min = INF;
//取出dist中最小的
for(j=0;j<g.n;j++)
{
    if(s[j]==0 && dist[j]<min)
    {
        min = dist[j];
        u = j;
    }
}
s[u] = 1;

從上面的程式碼就可以找出距離頂點0權值最小的那個點了,從上面的思路中我們有提到dist陣列儲存的就是當前距離頂點0的權值最小的各條邊。那麼現在,我們要找出第三個頂點了,可以先看看下面的程式碼:

for(j=0;j<g.n;j++)
{
    if(s[u]==0)
        if(g.edges[u][j]<INF && dist[u]+g.edges[u][j]<dist[j])
        {
            dist[j] = dist[u]+g.edges[u][j];
            path[j] = u;
        }
}

這一段程式碼完成的功能就是取出遍歷跟第二個頂點相連的所有頂點,判斷這些頂點與第一個頂點的距離會不會大於先連線第二個頂點再連線第一個頂點的距離,簡單點說就是現在有三個村莊a,b,c。那麼要做的就是判斷c村直接到a村比較近,還是先過b村,再去a村比較近。所以這一段就是迪克斯特拉演算法的精華之處
那麼整個演算法就是:

void Dijkstra(MGraph g,int v)
{
    int dist[MAXV],path[MAXV];
    int s[MAXV];
    int i,j,min,u;
    for(i=0;i<g.n;i++)
    {
        dist[i]=g.edges[v][i];
        s[i] = 0;
        if(g.edges[v][i]<INF)
            path[i] = g.edges[v][i];
        else
            path[i] = -1;       
    }

    for(i=0;i<g.n;i++)
    {
        min = INF;
        //取出dist中最小的
        for(j=0;j<g.n;j++)
        {
            if(s[j]==0 && dist[j]<min)
            {
                min = dist[j];
                u = j;
            }
        }
        //經過上面的遍歷已經取出dist中最小的了,接下來要做的就是訪問這個形成最小距離的頂點u
        //設定已經訪問
        s[u] = 1;
        for(j=0;j<g.n;j++)
        {
            if(s[u]==0)
                if(g.edges[u][j]<INF && dist[u]+g.edges[u][j]<dist[j])
                {
                    dist[j] = dist[u]+g.edges[u][j];
                    path[j] = u;
                }
        }
    }
}

相關推薦

路徑(Dijkstra)演算法

何謂最短路徑 顧名思義就是在一個圖中,一個頂點到另外一個頂點的最短距離拉。那麼這裡有一點要注意,就是在網圖中(邊的權值各不相同)最短路徑指的是倆點之間的連線權值最小;在非網圖(邊的權值都預設為1)中最短路徑指的是邊數最少的。 從一個頂點到其餘各頂點的最短

路徑算法的Java實現

spa visit art 方式 pat fin img 叠代算法 屬於   Dijkstra算法是最短路徑算法中為人熟知的一種,是單起點全路徑算法。該算法被稱為是“貪心算法”的成功典範。本文接下來將嘗試以最通俗的語言來介紹這個偉大的算法,並賦予java實現代碼。 一、知識

數據結構 - 單源路徑Dijkstra)算法詳解(Java)

previous 代碼 map class matrix () count 就是 可能   給出一個圖,求某個端點(goal)到其余端點或者某個端點的最短路徑,最容易想到的求法是利用DFS,假設求起點到某個端點走過的平均路徑為n條,每個端點的平均鄰接端點為m,那求出這個最短

單源路徑Dijkstra)演算法

Dijkstra演算法1.定義概覽Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點(節點需為源點)到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。Dijkstra演算法是很有代表性的最短路徑演算法,注

路徑演算法

問題:每個城市間的距離不一樣,任意選擇兩個城市,求出兩個城市間的最短距離 分析:用圖來表示城市和城市間的距離(鄰接矩陣),轉變成求圖的最短路徑 shortestPath.h #include <stdio.h> #define NUMVERTICES 10 #d

單源路徑Dijkstra)演算法的改進

Dijkstra演算法1.定義概覽Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點(節點需為源點)到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。Dijkstra演算法是很有代表性的最短路徑演算法,注

圖的路徑演算法和弗洛伊德演算法

一、迪傑斯特拉(Dijkstra)演算法 1、定義描述   Dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。Dijkstra演算法的時

路徑算法)

ace info urn itl int -- iostream pro src 求上圖中從V1 到V10的最短路徑 程序輸入說明 輸入圖的鄰接矩陣表示 程序輸出說明 輸出路徑序列 程序輸入樣例 0 2 5 1 -1

無向圖的Dijkstra演算法(求任意一對頂點間的路徑演算法

public class Main{ public static int dijkstra(int[][] w1,int start,int end) { boolean[] isLable = new boolean[w1[0].length];//是否標上所有的號 i

【圖】路徑Dijkstra演算法

網圖和非網圖中,最短路徑的含義不同: 非網圖中,因為沒有邊上的權值,最短路徑指的是兩頂點之間經過的邊數最少的路徑; 網圖中,最短路徑指的是兩頂點之間經過的邊上權值之和最少的路徑,並且稱路徑上的第一個

總結一下路徑演算法(Dijkstra)的基本內容以及用鄰接表優化

前面轉了兩篇部落格說了一下這個迪傑斯特拉演算法,現在自己嘗試總結一下。 先上一個百度百科的定義:迪傑斯特拉演算法 --------------------------------------------------------------------------------

路徑問題---dijkstra演算法

理解最短路徑——迪傑斯特拉(dijkstra)演算法 1.       迪傑斯特拉演算法簡介  迪傑斯特拉(dijkstra)演算法是典型的用來解決最短路徑的演算法,也是很多教程中的範例,由荷蘭電腦科學家狄克斯特拉於1959年提出,用來求得從起始點到其他所有點最短路徑

【模板】路徑、SPFA、弗洛伊德)

迪傑斯特拉演算法(Dijkstra's Algorithm)解決單源最短路問題的優秀演算法,堆優化後時間複雜度降到O((m+n)logn)。#include<iostream> #include<cmath> #include<cstdio>

有權路徑問題:狄(Dijkstra)演算法 & Java 實現

一、有權圖 之前我們知道,在無權重的圖中,求兩個頂點之間的最短路徑,可以使用 廣度優先搜尋 演算法。但是,當邊存在權重(也可以理解為路程的長度)時,廣度優先搜尋不再適用。 針對有權圖中的兩點間最短路徑,目前主要有 狄克斯特拉演算法 和 貝爾曼福德演算法 兩種解決

(Dijkstra)演算法求圖中路徑

迪傑斯特拉(Dijkstra )演算法: 對於圖G=(V,E),將圖的頂點分為兩組: 頂點集S:已求出的最短路徑的頂點集合(初始為{v0}); 頂點集V-S:尚未求出最短路徑的頂點集合(初始為V-{v0} )。 演算法按最短路徑長度的遞增順序逐個將

淺談短路——(Dijkstar)演算法

    迪傑斯特拉演算法複雜度為O(n^2),加入堆優化後可以優化到O((m+n)logn)的級別。主要適用於解決不含負邊權的單源最短路。其基本思想是:記S為已找到源點的最短路的點的集合,V為不在集合S中的點的集合,用dis陣列記錄i到源點的最短路徑長度,每次取V中w值最小的

Dijkstra 演算法 C#實現

今天在看《演算法圖解》,看了加權最小路徑演算法,決定用程式碼實現一下。 首先是畫有向圖,在網上找了一下,有不錯的開源軟體graphviz,該原始碼託管在GitLab上。該軟體是一個圖形視覺化軟體。 畫了一個有向圖如下: 畫圖用的程式碼: digraph dijkstra{ start->A[lab

(Dijkstra)演算法描述及其正確性證明

1. 演算法描述 Dijkstra演算法是圖論中常用的一個演算法,用於計算圖中從一個指定點到其餘所有點的最短路徑。圖是有向圖,所有邊的權重為非負數,圖1是滿足條件的一個簡單有向圖。 圖1 有向加權圖示例 在圖1中,A到D的最短路徑是A-->C-->B-->

資料結構---C語言實現路徑Dijkstra演算法

此處共有兩段程式碼: 一、 這段程式碼比較全面,其中參考了github上的相關原始碼。可以說功能強大。 //Dijkstra(迪傑斯特拉演算法) #include <stdio.h> #include <stdlib.h> #include <

圖|路徑——(Dijkstra)弗洛伊德(Floyd)

最短路徑——迪傑斯特拉(Dijkstra)弗洛伊德(Floyd) 一、迪傑斯特拉演算法(Dijkstra) 1. 問題: 求從每個源點到其餘各頂點的最短路徑。 2.儲存結構: 1)圖的儲存結構: 帶權的鄰接矩陣 2)輔助陣列: 一維陣列dist:dist[ i ]表示