数据结构:以一个例题演示弗洛伊德算法
例 8.5.2 利用弗洛伊德算法,对图 8.5.5 中左侧的带权有向图求最短路径,给出每一对顶点之间的最短路径及其路径长度在求解过程中的变化。

【解】
根据图 8.5.5 中的带权有向图,可得所对应的邻接矩阵 ggg ,如图 8.5.5 右侧图所示。
根据弗洛伊德算法,所对应的 4×44\times 44×4 的矩阵序列是:A−1,A0,A1,A2,A3 (n=4)\pmb{A}_{-1},\pmb{A}_0,\pmb{A}_1,\pmb{A}_2,\pmb{A}_3~(n=4)A−1,A0,A1,A2,A3 (n=4) 。
(1)A−1\pmb{A}_{-1}A−1 ,不经过任何中间结点,任何两个顶点之间的距离,即为邻接矩阵
A−1=g=[01∞4∞0923508∞∞60]
\begin{split}
\pmb{A}_{-1}=g=\begin{bmatrix}0&1&\infty&4\\\infty&0&9&2\\3&5&0&8\\\infty&\infty&6&0 \end{bmatrix}
\end{split}
A−1=g=0∞3∞105∞∞9064280
用矩阵 path−1\text{path}_{-1}path−1 保存此时的最短路径,注意,此时意味着两个顶点之间是否有直接地、不经过中间顶点的路径。如果顶点 iii 和顶点 jjj 之间有路径,则 path−1[i][j]=i\pmb{path}_{-1}[i][j]=ipath−1[i][j]=i ,否则 path−1[i][j]=−1\pmb{path}_{-1}[i][j]=-1path−1[i][j]=−1 。
- 元素 A−1[0][0]\pmb{A}_{-1}[0][0]A−1[0][0] (下标按照图 3 右侧的邻接矩阵方式表示),说明顶点 0 到顶点 0 没有路径,则 path−1[0][0]=−1\pmb{path}_{-1}[0][0]=-1path−1[0][0]=−1 。
- 元素 A−1[0][1]=1\pmb{A}_{-1}[0][1]=1A−1[0][1]=1 ,说明顶点 0 到顶点 1 的路径权值是 1 ,有路径,则 path−1[0][1]=0\pmb{path}_{-1}[0][1]=0path−1[0][1]=0 。
- 元素 A−1[0][2]=∞\pmb{A}_{-1}[0][2]=\inftyA−1[0][2]=∞ ,说明顶点 0 到顶点 2 没有路径,则 path−1[0][2]=−1\pmb{path}_{-1}[0][2] =-1path−1[0][2]=−1 。
- ⋯\cdots⋯
用上述方法,即可得到矩阵 path−1\pmb{path}_{-1}path−1 。具体实现的时候,可以按照行号观察 A−1\pmb{A}_{-1}A−1 ,在某一行中,其元素非 000 或者非 ∞\infty∞ ,则说明该行号到所对应列有路径,那么对应到 path−1\pmb{path}_{-1}path−1 中的相应位置元素即为 A−1\pmb{A}_{-1}A−1 中的该行的行号;否则为 −1-1−1 。所以得到矩阵 path−1\pmb{path}_{-1}path−1 如下:
path−1=[−10−10−1−11122−12−1−13−1]
\pmb{path}_{-1}=\begin{bmatrix}-1&0&-1&0\\-1&-1&1&1\\2&2&-1&2\\-1&-1&3&-1\end{bmatrix}
path−1=−1−12−10−12−1−11−13012−1
(2) A0\pmb{A}_0A0 ,以顶点 0 为中间点,任何两个顶点之间的最短距离,即 A0[i,j]=min(A−1[i,j],A−1[i,0])+A−1[0,j])\pmb{A}_0[i,j]=\min(\pmb{A}_{-1}[i,j],\pmb{A}_{-1}[i,0])+\pmb{A}_{-1}[0,j])A0[i,j]=min(A−1[i,j],A−1[i,0])+A−1[0,j]) 。
A0[0,0]=0A0[0,1]=min(A−1[0,1],A−1[0,0]+A−1[0,1])=1A0[0,2]=min(A−1[0,2],A−1[0,0]+A−1[0,2])=∞ ⋮A0[2,1]=min(A−1[2,1],A−1[2,0]+A−1[0,1])=4 ⋮
\begin{split}
&\pmb{A}_0[0,0] = 0
\\&\pmb{A}_0[0,1]=\min(\pmb{A}_{-1}[0,1],\pmb{A}_{-1}[0,0]+\pmb{A}_{-1}[0,1])=1
\\&\pmb{A}_0[0,2]=\min(\pmb{A}_{-1}[0,2],\pmb{A}_{-1}[0,0]+\pmb{A}_{-1}[0,2])=\infty
\\&~\vdots
\\&\pmb{A}_0[2,1]=\min(\pmb{A}_{-1}[2,1],\pmb{A}_{-1}[2,0]+\pmb{A}_{-1}[0,1])=4
\\&~\vdots
\end{split}
A0[0,0]=0A0[0,1]=min(A−1[0,1],A−1[0,0]+A−1[0,1])=1A0[0,2]=min(A−1[0,2],A−1[0,0]+A−1[0,2])=∞ ⋮A0[2,1]=min(A−1[2,1],A−1[2,0]+A−1[0,1])=4 ⋮
最终得到 A0\pmb{A}_0A0 如下:
A0=[01∞4∞0923407∞∞60]
\pmb{A}_0=\begin{bmatrix}0&1&\infty&4\\\infty&0&9&2\\3&4&0&7\\\infty&\infty&6&0\end{bmatrix}
A0=0∞3∞104∞∞9064270
如果 A0[i,j]=A1[i,j]\pmb{A}_0[i,j]=\pmb{A}_1[i,j]A0[i,j]=A1[i,j] ,则说明路径没有调整,即 path0[i,j]=path−1[i,j]\pmb{path}_0[i,j]=\pmb{path}_{-1}[i,j]path0[i,j]=path−1[i,j] 。
否则,路径已经调整,即:经过顶点 kkk 的路径较短,则 Ak[i][j]=Ak−1[i][k]+Ak−1[k][j]\pmb{A}_k[i][j]=\pmb{A}_{k-1}[i][k]+\pmb{A}_{k-1}[k][j]Ak[i][j]=Ak−1[i][k]+Ak−1[k][j] ,pathk[i][j]=a=pathk−1[k][j]\text{path}_k[i][j]=a=\text{path}_{k-1}[k][j]pathk[i][j]=a=pathk−1[k][j] ,所以有:path0[i,j]=path−1[0,j]\pmb{path}_0[i,j]=\pmb{path}_{-1}[0,j]path0[i,j]=path−1[0,j] 。
由以上规则,可得矩阵 path\pmb{path}path :
path0=[−10−10−1−11120−10−1−13−1]
\pmb{path}_{0}=\begin{bmatrix}-1&0&-1&0\\-1&-1&1&1\\2&0&-1&0\\-1&-1&3&-1\end{bmatrix}
path0=−1−12−10−10−1−11−13010−1
(3)A1\pmb{A}_1A1 ,以顶点 1 为中间点,任何两点之间的最短距离,即 A1[i,j]=min(A0[i,j],A0[i,1]+A0[1,j])\pmb{A}_1[i,j]=\min(\pmb{A}_0[i,j],\pmb{A}_0[i,1]+\pmb{A}_0[1,j])A1[i,j]=min(A0[i,j],A0[i,1]+A0[1,j]) 。
A1[0,0]=0A1[0,1]=min(A0[0,1],A0[0,1]+A0[1,1])=1A1[0,2]=min(A0[0,2],A0[0,1]+A0[1,2])=10A1[0,3]=min(A0[0,3],A0[0,1]+A0[1,3])=3A1[1,0]=min(A0[1,0],A0[1,1]+A0[1,0])=∞ ⋮
\begin{split}
&\pmb{A}_1[0,0]=0
\\&\pmb{A}_1[0,1]=\min(\pmb{A}_0[0,1],\pmb{A}_0[0,1]+\pmb{A}_0[1,1])=1
\\&\pmb{A}_1[0,2]=\min(\pmb{A}_0[0,2],\pmb{A}_0[0,1]+\pmb{A}_0[1,2])=10
\\&\pmb{A}_1[0,3]=\min(\pmb{A}_0[0,3],\pmb{A}_0[0,1]+\pmb{A}_0[1,3])=3
\\&\pmb{A}_1[1,0]=\min(\pmb{A}_0[1,0],\pmb{A}_0[1,1]+\pmb{A}_0[1,0])=\infty
\\~&\vdots
\end{split}
A1[0,0]=0A1[0,1]=min(A0[0,1],A0[0,1]+A0[1,1])=1A1[0,2]=min(A0[0,2],A0[0,1]+A0[1,2])=10A1[0,3]=min(A0[0,3],A0[0,1]+A0[1,3])=3A1[1,0]=min(A0[1,0],A0[1,1]+A0[1,0])=∞⋮
最终得到:
A1=[01103∞0923406∞∞60]
\pmb{A}_1=\begin{bmatrix}0&1&10&3\\\infty&0&9&2\\3&4&0&6\\\infty&\infty&6&0\end{bmatrix}
A1=0∞3∞104∞109063260
比较 A1\pmb{A}_1A1 和 A0\pmb{A}_0A0 ,若相等,则 path1[i,j]=path0[i,j]\pmb{path}_1[i,j]=\pmb{path}_0[i,j]path1[i,j]=path0[i,j] ,否则 path1[i,j]=path0[1,j]\pmb{path}_1[i,j]=\pmb{path}_0[1,j]path1[i,j]=path0[1,j] ,由此得到:
path1=[−1011−1−11120−11−1−13−1]
\pmb{path}_1=\begin{bmatrix}-1&0&1&1\\-1&-1&1&1\\2&0&-1&1\\-1&-1&3&-1\end{bmatrix}
path1=−1−12−10−10−111−13111−1
依照上述方法,继续计算 A2,A3\pmb{A}_2,\pmb{A}_3A2,A3 ,最终得到:
A3=[019311082340691060]path3=[−10312−13120−11203−1]
\begin{split}
&\pmb{A}_3=\begin{bmatrix}0&1&9&3\\11&0&8&2\\3&4&0&6\\9&10&6&0\end{bmatrix}
\\&\pmb{path}_3=\begin{bmatrix}-1&0&3&1\\2&-1&3&1\\2&0&-1&1\\2&0&3&-1\end{bmatrix}
\end{split}
A3=011391041098063260path3=−12220−10033−13111−1
由 A3[i,j]\pmb{A}_3[i,j]A3[i,j] 可以得出每一对顶点之间的最短距离,由 path3[i,j]\pmb{path}_3[i,j]path3[i,j] 能找出对应着该对顶点之间的路径。
例如:A3[1,2]=8\pmb{A}_3[1,2]=8A3[1,2]=8 ,即顶点 1 到顶点 2 的最短路径长度是 8。对应的路径:path3[1,2]=3\pmb{path}_3[1,2]=3path3[1,2]=3 ,即顶点 2 的前驱是顶点 3,即路径 <3,2><3,2><3,2> 。由于是从顶点 1 出发,顶点 3 是中间点。而从 1→31\to31→3 的路径:path3[1,3]=1\pmb{path}_3[1,3]=1path3[1,3]=1 ,即顶点 3 的前驱是 1。故从 1→21\to21→2 的路径是 <1,3,2><1,3,2><1,3,2> ,这条路径最短,长度是 8。
更多推荐
所有评论(0)