栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

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

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

目录
    • Dijkstra 算法 (求固定起点到其余各点的最短路)
      • 步骤
      • 示例
      • Python 实现
    • Floyd 算法 (求每对顶点间的最短路算法)
      • 迭代方式
      • 路由矩阵
      • 查找最短路径
      • 示例
      • Python 实现

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 ℓij​⩾0; 若结点 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=V−P, 且
{ d ( v i ) = W ( v 1 , v i ) , 若 v i v 1 相邻 d ( v i ) = ∞ , 否则 begin{cases} dleft(v_{i}right)=Wleft(v_{1}, v_{i}right), &text{若} v_{i} v_{1} text{相邻} \ dleft(v_{i}right)=infty, quad &text{否则} end{cases} {d(vi​)=W(v1​,vi​),d(vi​)=∞,​若vi​v1​相邻否则​

  • 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} ∀vi​∈T :
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} dleft(v_{l}right)+Wleft(v_{l}, v_{i}right) &text { 若 } dleft(v_{1}right)+Wleft(v_{i}, v_{i}right)d(vl​)+W(vl​,vi​)d(vi​)​ 若 d(v1​)+W(vi​,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} Step1Step2Step3Step4Step5​v2​1(v1​)​v3​43(v2​)​v4​∞887(v5​)​v5​∞64(v3​)​v6​∞∞∞109(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​:v1​→v2​(1)
v 3 : v 1 → v 2 → v 3 ( 3 ) v_3: v_1 rightarrow v_2 rightarrow v_3 quad (3) v3​:v1​→v2​→v3​(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​:v1​→v2​→v3​→v5​(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​:v1​→v2​→v3​→v5​→v4​(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​:v1​→v2​→v3​→v5​→v4​→v6​(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 & 2left(v_{2}right) text { 第1短 } \ operatorname{Step} 2 & & 4 & 3 & infty & 9 & infty & 3left(v_{4}right) text { 第2短 } \ operatorname{Step} 3 & & 4 & & 8 & 9 & infty & 4left(v_{3}right) text { 第3短 } \ text {Step } 4 & & & & 7 & 9 & infty & 7left(v_{5}right) text { 第4短 } \ text {Step } 5 & & & & & 8 & 14 & 8left(v_{6}right) text { 第5短 } \ text {Step } 6 & & & & & & 13 & 13left(v_{7}right) text { 第6短 } end{array} Step1Step2Step3Step 4Step 5Step 6​v2​2​v3​544​v4​33​v5​∞∞87​v6​∞9998​v7​∞∞∞∞1413​2(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)'.join(path))  #打印路径
    return dis
Floyd 算法 (求每对顶点间的最短路算法)

要求每对顶点间的最短路, 可多次使用 Dijkstra 算法, 每次以不同的顶点作为起点, 用 Dijkstra 算法求出从该起点到其余顶点的最短路径, 反复执行 n − 1 n-1 n−1 次这样的操作, 就可得到每对顶点之间的最短路. 但这样做需要大量的重复计算, 效率不高. 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(ak−1​(i,j),ak−1​(i,k)+ak−1​(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, 若 ak−1​(i,j)>ak−1​(i,k)+ak−1​(k,j),rk−1​(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}, jright)=q_{1}, r_{n}left(q_{1}, jright)=q_{2}, cdots, r_{n}left(q_{t}, jright)=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​.

示例

迭代 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​=⎣⎢⎢⎢⎢⎢⎢⎡​046∞∞∞​40221∞​620∞2∞​∞2∞013​∞12107​∞∞∞370​⎦⎥⎥⎥⎥⎥⎥⎤​,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​=⎣⎢⎢⎢⎢⎢⎢⎡​046∞∞∞​40221∞​620∞2∞​∞2∞013​∞12107​∞∞∞370​⎦⎥⎥⎥⎥⎥⎥⎤​,R1​=⎣⎢⎢⎢⎢⎢⎢⎡​000000​000000​000000​000000​000000​000000​⎦⎥⎥⎥⎥⎥⎥⎤​

迭代 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​=⎣⎢⎢⎢⎢⎢⎢⎡​04665∞​40221∞​62042∞​624013​512107​∞∞∞370​⎦⎥⎥⎥⎥⎥⎥⎤​,R2​=⎣⎢⎢⎢⎢⎢⎢⎡​000220​000000​000200​202000​200000​000000​⎦⎥⎥⎥⎥⎥⎥⎤​

迭代 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​=⎣⎢⎢⎢⎢⎢⎢⎡​04665∞​40221∞​62042∞​624013​512107​∞∞∞370​⎦⎥⎥⎥⎥⎥⎥⎤​,R3​=⎣⎢⎢⎢⎢⎢⎢⎡​000220​000000​000200​202000​200000​000000​⎦⎥⎥⎥⎥⎥⎥⎤​

迭代 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​=⎣⎢⎢⎢⎢⎢⎢⎡​046659​402215​620427​624013​512104​957340​⎦⎥⎥⎥⎥⎥⎥⎤​,R4​=⎣⎢⎢⎢⎢⎢⎢⎡​000224​000004​000204​202000​200004​444040​⎦⎥⎥⎥⎥⎥⎥⎤​

迭代 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​=⎣⎢⎢⎢⎢⎢⎢⎡​046659​402215​620326​623013​512104​956340​⎦⎥⎥⎥⎥⎥⎥⎤​,R5​=⎣⎢⎢⎢⎢⎢⎢⎡​000224​000004​000505​205000​200004​445040​⎦⎥⎥⎥⎥⎥⎥⎤​

迭代 6 ( n n n): 任意两节点之间的最短路, 最多可经过节点 1 、 2 … n 1 、 2 ldots n 1、2…n 到达, 因此当迭代 n {n} n 次时, 算法结束, 得到任意两点间的最短路及其距离.如本例题中, 节点 1 , 6 1, 6 1,6 之间的最短路为 1 − 2 − 4 − 6 1-2-4-6 1−2−4−6, 距离为 9 9 9; 节点 3 , 4 3, 4 3,4 之间的最短路为 3 − 5 − 4 3-5-4 3−5−4, 距离为 3 3 3; 节点 6 , 4 6, 4 6,4 之间的最短路为 6 − 4 6-4 6−4, 距离为 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​=⎣⎢⎢⎢⎢⎢⎢⎡​0466421​5521​96421​​402215642​​6203453​266453​​6124​23354​013​5125​12104645​​91246​5246​63546​34546​0​⎦⎥⎥⎥⎥⎥⎥⎤​,R6​=⎣⎢⎢⎢⎢⎢⎢⎡​000224​000004​000505​205000​200004​445040​⎦⎥⎥⎥⎥⎥⎥⎤​

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 为路由矩阵
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/883099.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号