数学建模:图论模型 — 最短路算法 (Dijkstra 算法与 Floyd 算法) 及 Python 实现

本文详细介绍了Dijkstra算法和Floyd算法,用于求解图中固定起点到其余各点的最短路径以及任意两点间的最短路径。Dijkstra算法通过逐步标记顶点的方式找到最短路径,而Floyd算法则通过动态规划计算所有顶点对的最短路径。同时,文中给出了两种算法的Python实现示例,帮助理解算法原理。
摘要由CSDN通过智能技术生成

Dijkstra 算法 (求固定起点到其余各点的最短路)

Dijkstra 算法时寻求从一固定起点 u 0 u_{0} u0 到其余各点的最短路最有效的算法之一, 由 E. W. Dijkstra 于 1959 年提出.

Dijkstra 算法的理论依据是一个重要而明显的性质: 最短路是一条路, 最短路上的任一子段也是最短路.

Dijkstra 算法的基本思想是:按距固定起点 u 0 u_{0} u0 从近到远为顺序, 依次求 得 u 0 u_{0} u0 到图 G G G 各顶点的最短路和距离, 直至某个顶点 v 0 v_{0} v0 (或直至图 G G G 的所有顶点).

步骤

设图 G G G n n n 个顶点; 边的长度 ℓ i j ⩾ 0 \ell_{i j} \geqslant 0 ij0; 若结点 v i v_i vi v j v_j vj 不相连, 则令 ℓ i j = ∞ \ell_{ij}=\infty ij=, 对每个结点 v i v_i vi, 令 ℓ i i = 0 \ell_{ii}=0 ii=0.

将顶点集 V V V 分成两部分,一部分为具有 P P P(永久性)标号的集合,另一部分为具有 T T T(暂时性)标号的集合。
结点 v v v P P P 标号是指从 v 1 v_1 v1 v v v 的最短路径的长度;顶点 u u u T T T 标号是指从 v 1 v_1 v1 u u u 某条路径的长度。
Dijkstras 算法首先将 v 1 v_1 v1 取为 P P P 标号,其余结点取为 T T T 标号,逐步将具有 T T T 标号的结点改为 P P P 标号。当结点 v n v_n vn 被改为 P P P 标号时,就找到一条从 v 1 v_1 v1 v n v_n vn 的最短路径。

  • Step 1: 初始化

v 1 {v}_{1} v1 置为 P {P} P 标号, d ( v 1 ) = 0 , P = { v 1 } ; ∀ v i ( i ≠ 1 ) {d}\left({v}_{1}\right)=0, {P}=\left\{{v}_{1}\right\}; \forall {v}_{{i}}({i} \neq 1) d(v1)=0,P={v1};vi(i=1), 置 v i {v}_{{i}} vi T {T} T 标号, 即 T = V − P T=V-P T=VP, 且
{ d ( v i ) = W ( v 1 , v i ) , 若 v i v 1 相邻 d ( v i ) = ∞ , 否则 \begin{cases} d\left(v_{i}\right)=W\left(v_{1}, v_{i}\right), &\text{若} v_{i} v_{1} \text{相邻} \\ d\left(v_{i}\right)=\infty, \quad &\text{否则} \end{cases} {d(vi)=W(v1,vi),d(vi)=,viv1相邻否则

  • Step 2: 找最小

寻找具有最小值的 T T T 标号的结点。若为 v l v_l vl,则将 v l v_l vl T T T 标号改为 P P P 标号,且 P = P ∪ { v l } , T = T − { v l } P=P \cup \{v_l\},T=T-\{v_l\} P=P{vl}T=T{vl}

  • Step 3:修改

修改与 v l {v_l} vl 相邻的结点的 T T T 标号的值。 ∀ v i ∈ T \forall {v_i} \in {T} viT :
d ( v i ) = { d ( v l ) + W ( v l , v i )  若  d ( v 1 ) + W ( v i , v i ) < d ( v i ) d ( v i )  否则  d(v_i)=\left\{\begin{array}{ll} d\left(v_{l}\right)+W\left(v_{l}, v_{i}\right) &\text { 若 } d\left(v_{1}\right)+W\left(v_{i}, v_{i}\right)<d\left(v_{i}\right) \\ d\left(v_{i}\right) \quad &\text { 否则 } \end{array}\right. d(vi)={d(vl)+W(vl,vi)d(vi)  d(v1)+W(vi,vi)<d(vi) 否则 

  • Step 4:重复 (2) 和 (3),直到 v n v_n vn 改为 P P P 标号为止。

示例

求无向图最短路

无向狄克斯特拉

  • Step 1:
    P = { v 1 ( 0 ) } P=\{v_1(0)\} P={v1(0)}
    T = { v 2 ( 1 , v 1 ) , v 3 ( 4 , v 1 ) , v 4 ( ∞ ) , v 5 ( ∞ ) , v 6 ( ∞ } T=\{v_2(1,v_1),v_3(4,v_1),v_4(\infty),v_5(\infty),v_6(\infty\} T={v2(1,v1),v3(4,v1),v4(),v5(),v6(}
  • Step 2:
    P = { v 1 ( 0 ) , v 2 ( 1 , v 1 ) } P=\{v_1(0),v_2(1,v_1)\} P={v1(0),v2(1,v1)}
    T = { v 3 ( 3 , v 1 , v 2 ) , v 4 ( 8 , v 1 , v 2 ) , v 5 ( 6 , v 1 , v 2 ) , v 6 ( ∞ ) } T=\{v_3(3,v_1,v_2),v_4(8,v_1,v_2),v_5(6,v_1,v_2),v_6(\infty)\} T={v3(3,v1,v2),v4(8,v1,v2),v5(6,v1,v2),v6()}
  • Step 3:
    P = { v 1 ( 0 ) , v 2 ( 1 , v 1 ) , v 3 ( 3 , v 1 , v 2 ) } P=\{v_1(0),v_2(1,v_1) , v_3(3,v_1,v_2)\} P={v1(0),v2(1,v1),v3(3,v1,v2)}
    T = { v 4 ( 8 , v 1 , v 2 ) , v 5 ( 4 , v 1 , v 2 , v 3 ) , v 6 ( ∞ ) } T=\{v_4(8,v_1,v_2),v_5(4,v_1,v_2,v_3),v_6(\infty)\} T={v4(8,v1,v2),v5(4,v1,v2,v3),v6()}
  • Step 4:
    P = { v 1 ( 0 ) , v 2 ( 1 , v 1 ) , v 3 ( 3 , v 1 , v 2 ) , v 5 ( 4 , v 1 , v 2 , v 3 ) } P=\{v_1(0),v_2(1,v_1) , v_3(3,v_1,v_2),v_5(4,v_1,v_2,v_3)\} P={v1(0),v2(1,v1),v3(3,v1,v2),v5(4,v1,v2,v3)}
    T = { v 4 ( 7 , v 1 , v 2 , v 3 , v 5 ) , v 6 ( 10 , v 1 , v 2 , v 3 , v 5 ) } T=\{v_4(7,v_1,v_2,v_3,v_5),v_6(10,v_1,v_2,v_3,v_5)\} T={v4(7,v1,v2,v3,v5),v6(10,v1,v2,v3,v5)}
  • Step 5:
    P = { v 1 ( 0 ) , v 2 ( 1 , v 1 ) , v 3 ( 3 , v 1 , v 2 ) , v 5 ( 4 , v 1 , v 2 , v 3 ) , v 4 ( 7 , v 1 , v 2 , v 3 , v 5 ) } P=\{v_1(0),v_2(1,v_1) , v_3(3,v_1,v_2),v_5(4,v_1,v_2,v_3),v_4(7,v_1,v_2,v_3,v_5)\} P={v1(0),v2(1,v1),v3(3,v1,v2),v5(4,v1,v2,v3),v4(7,v1,v2,v3,v5)}
    T = { v 6 ( 9 , v 1 , v 2 , v 3 , v 5 , v 4 ) } T=\{v_6(9,v_1,v_2,v_3,v_5,v_4)\} T={v6(9,v1,v2,v3,v5,v4)}
  • Step 6:
    P = { v 1 ( 0 ) , v 2 ( 1 , v 1 ) , v 3 ( 3 , v 1 , v 2 ) , v 5 ( 4 , v 1 , v 2 , v 3 ) , v 4 ( 7 , v 1 , v 2 , v 3 , v 5 ) , v 6 ( 9 , v 1 , v 2 , v 3 , v 5 , v 4 ) } P=\{v_1(0),v_2(1,v_1) , v_3(3,v_1,v_2),v_5(4,v_1,v_2,v_3),v_4(7,v_1,v_2,v_3,v_5),v_6(9,v_1,v_2,v_3,v_5,v_4)\} P={v1(0),v2(1,v1),v3(3,v1,v2),v5(4,v1,v2,v3),v4(7,v1,v2,v3,v5),v6(9,v1,v2,v3,v5,v4)}
    T = { } T=\{\} T={}

v 2 v 3 v 4 v 5 v 6 Step ⁡ 1 1 ( v 1 ) 4 ∞ ∞ ∞ ( v 2 ) 第 1 短 Step ⁡ 2 3 ( v 2 ) 8 6 ∞ ( v 3 ) 第 2 短 Step ⁡ 3 8 4 ( v 3 ) ∞ ( v 5 ) 第 3 短 Step ⁡ 4 7 ( v 5 ) 10 ( v 4 ) 第 4 短 Step ⁡ 5 9 ( v 4 ) ( v 6 ) 第 5 短 \begin{array}{l|ccccc} & {v}_{2} & {v}_{3} & {v}_{4} & {v}_{5} & {v}_{6} & \\ \hline \operatorname{Step} 1 & 1({v_{1}}) & 4 & \infty & \infty & \infty & (v_2)第1短 \\ \operatorname{Step} 2 & & 3(v_2) & 8 & 6 & \infty & (v_3)第2短 \\ \operatorname{Step} 3 & & & 8 & 4 (v_{3}) & {\infty} & (v_5)第3短 \\ \operatorname{Step} 4 & & & 7 (v_{5}) & & 10 & (v_4)第4短 \\ \operatorname{Step} 5 & & & & & 9 (v_{4}) & (v_6)第5短 \end{array} Step1Step2Step3Step4Step5v21(v1)v343(v2)v4887(v5)v564(v3)v6109(v4)(v2)1(v3)2(v5)3(v4)4(v6)5

所以 v 1 v_1 v1 到各顶点的最短路径和距离分别为:
v 2 : v 1 → v 2 ( 1 ) v_2: v_1 \rightarrow v_2 \quad (1) v2:v1v2(1)
v 3 : v 1 → v 2 → v 3 ( 3 ) v_3: v_1 \rightarrow v_2 \rightarrow v_3 \quad (3) v3:v1v2v3(3)
v 5 : v 1 → v 2 → v 3 → v 5 ( 4 ) v_5: v_1 \rightarrow v_2 \rightarrow v_3 \rightarrow v_5 \quad (4) v5:v1v2v3v5(4)
v 4 : v 1 → v 2 → v 3 → v 5 → v 4 ( 7 ) v_4: v_1 \rightarrow v_2 \rightarrow v_3 \rightarrow v_5 \rightarrow v_4 \quad (7) v4:v1v2v3v5v4(7)
v 6 : v 1 → v 2 → v 3 → v 5 → v 4 → v 6 ( 9 ) v_6: v_1 \rightarrow v_2 \rightarrow v_3 \rightarrow v_5 \rightarrow v_4 \rightarrow v_6 \quad (9) v6:v1v2v3v5v4v6(9)

求有向图最短路

有向狄克斯特拉
仿照上例

v 2 v 3 v 4 v 5 v 6 v 7 Step ⁡ 1 2 5 3 ∞ ∞ ∞ 2 ( v 2 )  第1短  Step ⁡ 2 4 3 ∞ 9 ∞ 3 ( v 4 )  第2短  Step ⁡ 3 4 8 9 ∞ 4 ( v 3 )  第3短  Step  4 7 9 ∞ 7 ( v 5 )  第4短  Step  5 8 14 8 ( v 6 )  第5短  Step  6 13 13 ( v 7 )  第6短  \begin{array}{c|ccccccr} & {v}_{2} & {v}_{3} & {v}_{4} & {v}_{5} & {v}_{6} & {v}_{7} & \\ \hline \operatorname{Step} 1 & 2 & 5 & 3 & \infty & \infty & \infty & 2\left(v_{2}\right) \text { 第1短 } \\ \operatorname{Step} 2 & & 4 & 3 & \infty & 9 & \infty & 3\left(v_{4}\right) \text { 第2短 } \\ \operatorname{Step} 3 & & 4 & & 8 & 9 & \infty & 4\left(v_{3}\right) \text { 第3短 } \\ \text {Step } 4 & & & & 7 & 9 & \infty & 7\left(v_{5}\right) \text { 第4短 } \\ \text {Step } 5 & & & & & 8 & 14 & 8\left(v_{6}\right) \text { 第5短 } \\ \text {Step } 6 & & & & & & 13 & 13\left(v_{7}\right) \text { 第6短 } \end{array} Step1Step2Step3Step 4Step 5Step 6v22v3544v433v587v69998v714132(v2) 1 3(v4) 2 4(v3) 3 7(v5) 4 8(v6) 5 13(v7) 6 

Python 实现

import numpy as np
def Dijkstra_all_minpath(matr,start): #matr为邻接矩阵的数组,start表示起点
    n=len( matr) #该图的节点数
    dis=[]; temp=[]
    dis.extend(matr[start])  #添加数组matr的start行元素
    temp.extend(matr[start]) #添加矩阵matr的start行元素
    temp[start] = np.inf  #临时数组会把处理过的节点的值变成 \infty
    visited=[start]  #start已处理
    parent=[start]*n   #用于画路径,记录此路径中该节点的父节点
    while len(visited)<n:
        i= temp.index(min(temp)) #找最小权值的节点的坐标
        temp[i]=np.inf
        for j in range(n):
            if j not in visited:
                if (dis[i]+ matr[i][j])<dis[j]:
                    dis[j] = temp[j] =dis[i]+ matr[i][j]
                    parent[j]=i  #说明父节点是i
        visited.append(i)  #该索引已经处理了
        path=[]  #用于画路径
        path.append(str(i))
        k=i
        while(parent[k]!=start):  #找该节点的父节点添加到path,直到父节点是start
            path.append(str(parent[k]))
            k=parent[k]
        path.append(str(start))
        path.reverse()   #path反序产生路径
        print(str(i)+':','->'.join(path))  #打印路径
    return dis

Floyd 算法 (求每对顶点间的最短路算法)

要求每对顶点间的最短路, 可多次使用 Dijkstra 算法, 每次以不同的顶点作为起点, 用 Dijkstra 算法求出从该起点到其余顶点的最短路径, 反复执行 n − 1 n-1 n1 次这样的操作, 就可得到每对顶点之间的最短路. 但这样做需要大量的重复计算, 效率不高. R. W. Floyd 于 1962 年提出了一个直接寻求任意两顶点之间最短路的算法.

迭代方式

Floyd 算法是一个经典的动态规划算法, 其基本思想是递推产生一个矩阵序列 A 1 , A 2 , ⋯   , A k , ⋯   , A n A_{1}, A_{2}, \cdots, A_{k}, \cdots, A_{n} A1,A2,,Ak,,An, 其中矩阵 A k = ( a k ( i , j ) ) n × n A_{k}=\left(a_{k}(i, j)\right)_{n \times n} Ak=(ak(i,j))n×n, 其第 i i i 行第 j j j 列元素 a k ( i , j ) a_{k}(i, j) ak(i,j) 表示从顶点 v i v_{i} vi 到顶点 v j v_{j} vj 的路径上所经过的顶点序号不大于 k k k 的最短路径长度.

计算时用迭代公式
a k ( i , j ) = min ⁡ ( a k − 1 ( i , j ) , a k − 1 ( i , k ) + a k − 1 ( k , j ) ) , a_{k}(i, j)=\min \left(a_{k-1}(i, j), a_{k-1}(i, k)+a_{k-1}(k, j)\right), ak(i,j)=min(ak1(i,j),ak1(i,k)+ak1(k,j)),

k k k 是迭代次数, i , j , k = 1 , 2 , ⋯   , n i, j, k=1,2, \cdots, n i,j,k=1,2,,n. A 0 A_0 A0 为邻接矩阵, 当 k = n k=n k=n 时, A n A_{n} An 即是各顶点之间的最短距离值.

路由矩阵

如果在求得两点间的最短距离时, 还需要求得两点间的最短路径, 需要在上面距离矩阵 A k A_{k} Ak 的迭代过程中, 引入一个路由矩阵 R k = ( r k ( i , j ) ) n × n R_{k}=\left(r_{k}(i, j)\right)_{n \times n} Rk=(rk(i,j))n×n 来记录两点间路径的前驱后继关系, 其中 r k ( i , j ) r_{k}(i, j) rk(i,j) 表示从顶点 v i v_{i} vi 到顶点 v j v_{j} vj 的路径经过编号为 r k ( i , j ) r_{k}(i, j) rk(i,j) 的顶点.

路由矩阵的迭代过程如下:

(1) 初始时
R 0 = 0 n × n {R}_{0}=\boldsymbol{0}_{n \times n} R0=0n×n
(2) 迭代公式为
R k = ( r k ( i , j ) ) n × n , R_{k}=\left(r_{k}(i, j)\right)_{n \times n}, Rk=(rk(i,j))n×n,

其中
r k ( i , j ) = { k ,  若  a k − 1 ( i , j ) > a k − 1 ( i , k ) + a k − 1 ( k , j ) , r k − 1 ( i , j ) ,  否则.  r_{k}(i, j)=\left\{\begin{array}{l} k, \quad \text { 若 } a_{k-1}(i, j)>a_{k-1}(i, k)+a_{k-1}(k, j), \\ r_{k-1}(i, j), \quad \text { 否则. } \end{array}\right. rk(i,j)={k,  ak1(i,j)>ak1(i,k)+ak1(k,j),rk1(i,j), 否则

直到迭代到 k = n k=n k=n, 算法终止.

查找最短路径

查找 v i v_{i} vi v j v_{j} vj 最短路径的方法如下:

r n ( i , j ) = p 1 r_{n}(i, j)=p_{1} rn(i,j)=p1, 则点 v p 1 v_{p_{1}} vp1 是顶点 v i v_{i} vi 到顶点 v j v_{j} vj 的最短路的中间点, 然后用同样的方法再分头查找. 若

(1) 向顶点 v i v_{i} vi 反向追踪得: r n ( i , p 1 ) = p 2 , r n ( i , p 2 ) = p 3 , ⋯   , r n ( i , p s ) = 0 r_{n}\left(i, p_{1}\right)=p_{2}, r_{n}\left(i, p_{2}\right)=p_{3}, \cdots, r_{n}\left(i, p_{s}\right)=0 rn(i,p1)=p2,rn(i,p2)=p3,,rn(i,ps)=0;

(2) 向顶点 v j v_{j} vj 正向追踪得: r n ( p 1 , j ) = q 1 , r n ( q 1 , j ) = q 2 , ⋯   , r n ( q t , j ) = 0 r_{n}\left(p_{1}, j\right)=q_{1}, r_{n}\left(q_{1}, j\right)=q_{2}, \cdots, r_{n}\left(q_{t}, j\right)=0 rn(p1,j)=q1,rn(q1,j)=q2,,rn(qt,j)=0;

则由点 v i v_{i} vi v j v_{j} vj 的最短路径为: v i , v p s , ⋯   , v p 2 , v p 1 , v q 1 , v q 2 , ⋯   , v q t , v j v_{i}, v_{p_{s}}, \cdots, v_{p_{2}}, v_{p_{1}}, v_{q_{1}}, v_{q_{2}}, \cdots, v_{q_{t}}, v_{j} vi,vps,,vp2,vp1,vq1,vq2,,vqt,vj.

示例

Floyd

迭代 0:
A 0 = [ 0 4 6 ∞ ∞ ∞ 4 0 2 2 1 ∞ 6 2 0 ∞ 2 ∞ ∞ 2 ∞ 0 1 3 ∞ 1 2 1 0 7 ∞ ∞ ∞ 3 7 0 ] , R 0 = ( 0 ) 6 × 6 A_{0}=\left[\begin{array}{c} 0 & 4 & 6 & \infty & \infty & \infty \\ 4 & 0 & 2 & 2 & 1 & \infty \\ 6 & 2 & 0 & \infty & 2 & \infty \\ \infty & 2 & \infty & 0 & 1 & 3 \\ \infty & 1 & 2 & 1 & 0 & 7 \\ \infty & \infty & \infty & 3 & 7 & 0 \end{array}\right], {R}_{0}=(0)_{6 \times 6} A0=046402216202201312107370,R0=(0)6×6

迭代 1: A 1 A_1 A1 的元素 a ( i , j ) a(i, j) a(i,j) 的意义为 i i i 直接到达 j j j 及经节点 1 到达 j {j} j 的两种方式中, 最短路线的距离
A 1 = [ 0 4 6 ∞ ∞ ∞ 4 0 2 2 1 ∞ 6 2 0 ∞ 2 ∞ ∞ 2 ∞ 0 1 3 ∞ 1 2 1 0 7 ∞ ∞ ∞ 3 7 0 ] , R 1 = [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] \mathrm{A}_{1}=\left[\begin{array}{c} 0 & 4 & 6 & \infty & \infty & \infty \\ 4 & 0 & 2 & 2 & 1 & \infty \\ 6 & 2 & 0 & \infty & 2 & \infty \\ \infty & 2 & \infty & 0 & 1 & 3 \\ \infty & 1 & 2 & 1 & 0 & 7 \\ \infty & \infty & \infty & 3 & 7 & 0 \end{array}\right] , {R}_{1}=\left[\begin{array}{c} 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \end{array}\right] A1=046402216202201312107370,R1=000000000000000000000000000000000000

迭代 2: A 2 A_2 A2 的元素 a ( i , j ) a(i, j) a(i,j) 的意义为 i i i 直接到达 j j j 及最多经节点 1, 2 到达 j {j} j 的所有方式中, 最短路线的距离
A 2 = [ 0 4 6 6 5 ∞ 4 0 2 2 1 ∞ 6 2 0 4 2 ∞ 6 2 4 0 1 3 5 1 2 1 0 7 ∞ ∞ ∞ 3 7 0 ] , R 2 = [ 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 2 0 0 2 0 2 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 ] A_{2}=\left[\begin{array}{c} 0 & 4 & 6 & 6 & 5 & \infty \\ 4 & 0 & 2 & 2 & 1 & \infty \\ 6 & 2 & 0 & 4 & 2 & \infty \\ 6 & 2 & 4 & 0 & 1 & 3 \\ 5 & 1 & 2 & 1 & 0 & 7 \\ \infty & \infty & \infty & 3 & 7 & 0 \end{array}\right], R_{2}=\left[\begin{array}{c} 0 & 0 & 0 & 2 & 2 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 2 & 0 & 0 \\ 2 & 0 & 2 & 0 & 0 & 0 \\ 2 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \end{array}\right] A2=046654022162042624013512107370,R2=000220000000000200202000200000000000

迭代 3:
A 3 = [ 0 4 6 6 5 ∞ 4 0 2 2 1 ∞ 6 2 0 4 2 ∞ 6 2 4 0 1 3 5 1 2 1 0 7 ∞ ∞ ∞ 3 7 0 ] , R 3 = [ 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 2 0 0 2 0 2 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 ] \mathrm{A}_{3}=\left[\begin{array}{c} 0 & 4 & 6 & 6 & 5 & \infty \\ 4 & 0 & 2 & 2 & 1 & \infty \\ 6 & 2 & 0 & 4 & 2 & \infty \\ 6 & 2 & 4 & 0 & 1 & 3 \\ 5 & 1 & 2 & 1 & 0 & 7 \\ \infty & \infty & \infty & 3 & 7 & 0 \end{array}\right], {R}_{3}=\left[\begin{array}{c} 0 & 0 & 0 & 2 & 2 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 2 & 0 & 0 \\ 2 & 0 & 2 & 0 & 0 & 0 \\ 2 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \end{array}\right] A3=046654022162042624013512107370,R3=000220000000000200202000200000000000

迭代 4:
A 4 = [ 0 4 6 6 5 9 4 0 2 2 1 5 6 2 0 4 2 7 6 2 4 0 1 3 5 1 2 1 0 4 9 5 7 3 4 0 ] , R 4 = [ 0 0 0 2 2 4 0 0 0 0 0 4 0 0 0 2 0 4 2 0 2 0 0 0 2 0 0 0 0 4 4 4 4 0 4 0 ] \mathrm{A}_{4}=\left[\begin{array}{c} 0 & 4 & 6 & 6 & 5 & 9 \\ 4 & 0 & 2 & 2 & 1 & 5 \\ 6 & 2 & 0 & 4 & 2 & 7 \\ 6 & 2 & 4 & 0 & 1 & 3 \\ 5 & 1 & 2 & 1 & 0 & 4 \\ 9 & 5 & 7 & 3 & 4 & 0 \end{array}\right], {R}_{4}=\left[\begin{array}{c} 0 & 0 & 0 & 2 & 2 & 4 \\ 0 & 0 & 0 & 0 & 0 & 4 \\ 0 & 0 & 0 & 2 & 0 & 4 \\ 2 & 0 & 2 & 0 & 0 & 0 \\ 2 & 0 & 0 & 0 & 0 & 4 \\ 4 & 4 & 4 & 0 & 4 & 0 \end{array}\right] A4=046659402215620427624013512104957340,R4=000224000004000204202000200004444040

迭代 5:
A 5 = [ 0 4 6 6 5 9 4 0 2 2 1 5 6 2 0 3 2 6 6 2 3 0 1 3 5 1 2 1 0 4 9 5 6 3 4 0 ] , R 5 = [ 0 0 0 2 2 4 0 0 0 0 0 4 0 0 0 5 0 5 2 0 5 0 0 0 2 0 0 0 0 4 4 4 5 0 4 0 ] \mathrm{A}_{5}=\left[\begin{array}{c} 0 & 4 & 6 & 6 & 5 & 9 \\ 4 & 0 & 2 & 2 & 1 & 5 \\ 6 & 2 & 0 & 3 & 2 & 6 \\ 6 & 2 & 3 & 0 & 1 & 3 \\ 5 & 1 & 2 & 1 & 0 & 4 \\ 9 & 5 & 6 & 3 & 4 & 0 \end{array}\right], {R}_{5}=\left[\begin{array}{c} 0 & 0 & 0 & 2 & 2 & 4 \\ 0 & 0 & 0 & 0 & 0 & 4 \\ 0 & 0 & 0 & 5 & 0 & 5 \\ 2 & 0 & 5 & 0 & 0 & 0 \\ 2 & 0 & 0 & 0 & 0 & 4 \\ 4 & 4 & 5 & 0 & 4 & 0 \end{array}\right] A5=046659402215620326623013512104956340,R5=000224000004000505205000200004445040

迭代 6 ( n n n): 任意两节点之间的最短路, 最多可经过节点 1 、 2 … n 1 、 2 \ldots n 12n 到达, 因此当迭代 n {n} n 次时, 算法结束, 得到任意两点间的最短路及其距离.如本例题中, 节点 1 , 6 1, 6 1,6 之间的最短路为 1 − 2 − 4 − 6 1-2-4-6 1246, 距离为 9 9 9; 节点 3 , 4 3, 4 3,4 之间的最短路为 3 − 5 − 4 3-5-4 354, 距离为 3 3 3; 节点 6 , 4 6, 4 6,4 之间的最短路为 6 − 4 6-4 64, 距离为 3 3 3 , 等等.

A 6 = [ 0 4 6 6 124 5 125 9 1246 4 0 2 2 1 5 246 6 2 0 3 354 2 6 3546 6 421 2 3 453 0 1 3 5 521 1 2 1 0 4 546 9 6421 5 642 6 6453 3 4 645 0 ] , R 6 = [ 0 0 0 2 2 4 0 0 0 0 0 4 0 0 0 5 0 5 2 0 5 0 0 0 2 0 0 0 0 4 4 4 5 0 4 0 ] \mathrm{A}_{6}=\left[\begin{array}{c} 0 & 4 & 6 & 6_{124} & 5_{125} & 9_{1246} \\ 4 & 0 & 2 & 2 & 1 & 5_{246} \\ 6 & 2 & 0 & 3_{354} & 2 & 6_{3546} \\ 6_{421} & 2 & 3_{453} & 0 & 1 & 3 \\ 5_{521} & 1 & 2 & 1 & 0 & 4_{546} \\ 9_{6421} & 5_{642} & 6_{6453} & 3 & 4_{645} & 0 \end{array}\right], {R}_{6}=\left[\begin{array}{c} 0 & 0 & 0 & 2 & 2 & 4 \\ 0 & 0 & 0 & 0 & 0 & 4 \\ 0 & 0 & 0 & 5 & 0 & 5 \\ 2 & 0 & 5 & 0 & 0 & 0 \\ 2 & 0 & 0 & 0 & 0 & 4 \\ 4 & 4 & 5 & 0 & 4 & 0 \end{array}\right] A6=0466421552196421402215642620345326645361242335401351251210464591246524663546345460,R6=000224000004000505205000200004445040

Python 实现

import numpy as np
def floyd(graph):
    m = len(graph)
    dis = graph
    path = np.zeros((m, m))  #路由矩阵初始化
    for k in range(m):
        for i in range(m):
            for j in range(m):
                if dis[i][k] + dis[k][j] < dis[i][j]:
                    dis[i][j] = dis[i][k] + dis[k][j]
                    path[i][j] = k
    return dis, path
    # dis 为各顶点的最短距离矩阵
    # path 为路由矩阵
  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值