最短路径算法——迪杰斯特拉算法(Dijkstra)
\qquad
最短路径问题是在一个网络中求一条从出发点到目的点的最短路径。
\qquad
这里会介绍求解有圈网络和无圈网络的2个算法:迪杰斯特拉算法(Dijkstra)、弗洛伊德算法(Floyd)。Dijkstra算法可以求网络中从源点到任何一个节点的最短路径,而Floyd算法的应用更加广泛,可以求网络中任意两点之间的最短路径。
1迪杰斯特拉算法(Dijkstra)
1.1 各种定义
\qquad
s
i
s_i
si表示从源点到节点
i
i
i的最短距离,
d
i
j
d_{ij}
dij(≥0)表示弧
(
i
,
j
)
(i,j)
(i,j)的长度。
\qquad
根据上述两个定义给出某一节点
j
j
j的标号(标号–通过数据对某一节点进行表示):
[
s
j
,
i
]
=
[
s
i
+
d
i
j
,
i
]
,
d
i
j
≥
0
[s_j,i]=[s_i + d_{ij}, i],d_{ij}≥0
[sj,i]=[si+dij,i],dij≥0
\qquad
用该式表示节点
j
j
j,
[
s
j
,
i
]
[s_j,i]
[sj,i]中的
s
j
s_j
sj表示源点到节点
j
j
j的最短距离,
i
i
i表示节点
j
j
j的“父节点”(来源节点)为
i
i
i,即节点
j
j
j的上一个节点是节点
i
i
i;
[
s
i
+
d
i
j
,
i
]
[s_i + d_{ij}, i]
[si+dij,i]中的
s
i
+
d
i
j
s_i + d_{ij}
si+dij表示源点到节点
j
j
j的最短距离=源点到节点
i
i
i的最短距离+弧
(
i
,
j
)
(i,j)
(i,j)的长度。
\qquad
在Dijkstra算法中存在两种节点
j
j
j的标号:暂时的、永久的。对于某一节点,如果找不到更短的路径达到该节点,则此时该节点的标号为永久的,否则则为暂时的。
1.2 步骤
第0步:对源点(节点1)进行永久地标号[0, -]. 令
i
=
1
i=1
i=1.
第1步:
\qquad
<1>计算节点
i
i
i有边相连的每一个暂时节点
j
j
j(
j
j
j不是永久的)
[
s
i
+
d
i
j
,
i
]
[s_i + d_{ij}, i]
[si+dij,i]. 如果节点
j
j
j已经被另一个节点
k
k
k连接并表示为
[
s
j
,
k
]
[s_j,k]
[sj,k],并且
s
i
+
d
i
j
<
s
j
s_i + d_{ij}<s_j
si+dij<sj,则用
[
s
i
+
d
i
j
,
i
]
[s_i + d_{ij}, i]
[si+dij,i]代替
[
s
j
,
k
]
[s_j,k]
[sj,k].
\qquad
<2> 如果所有节点都是永久的,那么停止。否则,从所有暂时标号的节点中选择具有最短距离的进行永久标号
[
s
r
,
l
]
[s_r,l]
[sr,l]。令
i
=
r
i=r
i=r,重复执行第
i
i
i步。
2 栗子
\qquad 下图网络中给出了城市1(节点1)和其他4个城市(节点2到节点5)之间可能的路线以及每条边的长度。求城市1到其他4个城市的最短路径。
迭代0:给节点1分配永久标号[0, -].
迭代1:节点1可以直接到达节点2、3,如下表
|
|
|
---|---|---|
|
|
|
|
|
|
|
|
|
表中有两个暂时标号[100,1]和[30,1],其中,节点3的距离较小 s 3 = 30 s_3=30 s3=30,因此把节点3的标号的状态转变为永久的。如下表:
|
|
|
---|---|---|
|
|
|
|
|
|
|
|
|
迭代2:节点3可以直接到达节点4和节点5,因此各个节点的标号变为:
|
|
|
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\qquad 表中有三个暂时标号[100,1]、[40,3]和[90,3],其中,节点4的距离较小 s 4 = 40 s_4=40 s4=40,因此把节点4的标号的状态转变为永久的。
|
|
|
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
迭代3:节点4可以直接到达节点2和节点5,则此时发现通过路径1-3-4-2到达节点2比路径1-2更短,即[55,4]中的55<[100,1]中的100;而路径1-3-5和1-3-4-5长度一样,得到下表
|
|
|
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\qquad 此时,在暂时节点中,节点2的距离 s 2 = 55 s_2=55 s2=55最小,并且,又因为节点2只能到节点3,而节点3已经是永久标号,不能改变,因此把节点2标记为永久。此时唯一剩下的暂时节点5也只能永久标号。
|
|
|
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\qquad
最后按照每个节点标号进行回溯,找到节点1(源点)到其他节点的最短路径。如对于节点2,:
节点2→[55,4]→节点4→[40,3]→节点3→[30,1]→节点1,所求最短路径为1→3→4→2,距离为55.
\qquad
这是迪杰斯特拉算法,在党耀国主编的《运筹学》中,其实表现形式更加简单,有兴趣的读者可以去看一下。