迪傑斯特拉演算法介紹

2021-09-06 20:05:07 字數 3594 閱讀 9075

迪傑斯特拉(dijkstra)演算法是典型最短路徑演算法,用於計算乙個節點到其他節點的最短路徑。 

它的主要特點是以起始點為中心向外層層擴充套件(廣度優先搜尋思想),直到擴充套件到終點為止。

基本思想

通過dijkstra計算圖g中的最短路徑時,需要指定起點s(即從頂點s開始計算)。

此外,引進兩個集合s和u。s的作用是記錄已求出最短路徑的頂點(以及相應的最短路徑長度),而u則是記錄還未求出最短路徑的頂點(以及該頂點到起點s的距離)。

初始時,s中只有起點s;u中是除s之外的頂點,並且u中頂點的路徑是"起點s到該頂點的路徑"。然後,從u中找出路徑最短的頂點,並將其加入到s中;接著,更新u中的頂點和頂點對應的路徑。 然後,再從u中找出路徑最短的頂點,並將其加入到s中;接著,更新u中的頂點和頂點對應的路徑。 ... 重複該操作,直到遍歷完所有頂點。

操作步驟

(1)初始時,s只包含起點s;u包含除s外的其他頂點,且u中頂點的距離為"起點s到該頂點的距離"[例如,u中頂點v的距離為(s,v)的長度,然後s和v不相鄰,則v的距離為∞]。

(2)從u中選出"距離最短的頂點k",並將頂點k加入到s中;同時,從u中移除頂點k。

(3)更新u中各個頂點到起點s的距離。之所以更新u中頂點的距離,是由於上一步中確定了k是求出最短路徑的頂點,從而可以利用k來更新其它頂點的距離;例如,(s,v)的距離可能大於(s,k)+(k,v)的距離。

(4)重複步驟(2)和(3),直到遍歷完所有頂點。

單純的看上面的理論可能比較難以理解,下面通過例項來對該演算法進行說明。

以上圖g4為例,來對迪傑斯特拉進行演算法演示(以第4個頂點d為起點)。

初始狀態:s是已計算出最短路徑的頂點集合,u是未計算除最短路徑的頂點的集合! 

第1步:將頂點d加入到s中。 

此時,s=, u=。     注:c(3)表示c到起點d的距離是3。

第2步:將頂點c加入到s中。 

上一步操作之後,u中頂點c到起點d的距離最短;因此,將c加入到s中,同時更新u中頂點的距離。以頂點f為例,之前f到d的距離為∞;但是將c加入到s之後,f到d的距離為9=(f,c)+(c,d)。 

此時,s=, u=。

第3步:將頂點e加入到s中。 

上一步操作之後,u中頂點e到起點d的距離最短;因此,將e加入到s中,同時更新u中頂點的距離。還是以頂點f為例,之前f到d的距離為9;但是將e加入到s之後,f到d的距離為6=(f,e)+(e,d)。 

此時,s=, u=。

第4步:將頂點f加入到s中。 

此時,s=, u=。

第5步:將頂點g加入到s中。 

此時,s=, u=。

第6步:將頂點b加入到s中。 

此時,s=, u=。

第7步:將頂點a加入到s中。 

此時,s=。

此時,起點d到各個頂點的最短距離就計算出來了:a(22) b(13) c(3) d(0) e(4) f(6) g(12)

以"鄰接矩陣"為例對迪傑斯特拉演算法進行說明,對於"鄰接表"實現的圖在後面會給出相應的原始碼。

1. 基本定義

//

鄰接矩陣

typedef struct

_graph

graph, *pgraph;

//邊的結構體

typedef struct

_edgedata

edata;

graph是鄰接矩陣對應的結構體。 

vexs用於儲存頂點,vexnum是頂點數,edgnum是邊數;matrix則是用於儲存矩陣資訊的二維陣列。例如,matrix[i][j]=1,則表示"頂點i(即vexs[i])"和"頂點j(即vexs[j])"是鄰接點;matrix[i][j]=0,則表示它們不是鄰接點。 

edata是鄰接矩陣邊對應的結構體。

2. 迪傑斯特拉演算法

#include#include

#include

#include

#define max 100

#define inf (~(0x1<<31))typedef

struct

graph

graph,*pgraph;

typedef

struct

edgedata

edata;

static

int get_position(graph g,char

ch)graph*create_graph()

;

int matrix[7]=,,,

,,,};

int vlen=sizeof(vexs)/sizeof(vexs[0

]);

inti,j;

graph *pg;

if((pg=(graph*)malloc(sizeof(graph)))==null)

return

null;

memset(pg,

0,sizeof

(pg));

pg->vexnum=vlen;

for(i=0; ivexnum; i++)

pg->vexs[i]=vexs[i];

for(i=0; ivexnum; i++)

for(j=0; jvexnum; j++)

pg->matrix[i][j]=matrix[i][j];

for(i=0; ivexnum; i++)

}pg->edgnum/=2

;

return

pg;}

void

print_graph(graph g)

}edata*get_edges(graph g)}}

return

edges;

}void dijkstra(graph g,int vs,int prev,int

dist)

flag[vs]=1

; dist[vs]=0

;

for(i=1;i)

}flag[k]=1

;

for(j=0;j)}}

printf(

"dijktra(%c):\n

",g.vexs[vs]);

for(i=0;i)

printf(

"shortest (%c,%c)=%d\n

",g.vexs[vs],g.vexs[i],dist[i]);

}int

main()

執行結果:

迪傑斯特拉演算法

if object id t test is not null drop table t test gocreate table dbo t test id int identity 1,1 not null primary key,自增字段,無意義 header varchar 500 第一點的名...

迪傑斯特拉演算法

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

迪傑斯特拉演算法

迪傑斯特拉演算法用來計算圖中某一點到其他點的最短距離,這個圖可以是加權,也可以是無權的,距離指的是從一點到其它點所經過的邊的權重和 假設現在有乙個加權無向圖,我們要求節點1到其他點的最短距離 初始化圖arr 用乙個鄰接矩陣來表示一張圖,矩陣元素 初始化一維向量d,這個向量儲存的是其他點的最短距離,初...