Floyd算法

216 阅读1分钟

「这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战」。

Floyd算法

每一对顶点的最短路径问题

【问题】给定带权有向图 G=(V, E) ,对任意顶点 vi 和vj(i ≠ j),求从顶点 vi 到顶点 vj 的最短路径
【算法】Floyd算法

Floyd算法——基本思想

w<vi, vj>:从顶点 vi 到顶点 vj 的权值
distk(vi, vj):从顶点 vi 到顶点 vj 经过的顶点编号不大于 k 的最短路径长度

Floyd算法描述

算法:Floyd算法
输入:带权有向图 G=(V,E) 
输出:每一对顶点的最短路径
        1. 初始化:假设从 vi 到 vj 的弧是最短路径,即dist-1(vi, vj)=w<vi, vj>;
        2. 循环变量 k 从 0~n-1 进行 n 次迭代:
             distk(vi, vj)=min{distk-1(vi, vj), distk-1(vi, vk)+distk-1(vk, vj)}

如何存储dist? 如何存储带权有向图?
邻接矩阵
dist-1(vi, vj) = w<vi, vj>
distk(vi, vj) = min{distk-1(vi, vj), distk-1(vi, vk)+distk-1(vk, vj)}

Floyd算法——运行实例

初始化

image.png

image.png

void Floyd(MGraph *G)
{
    int i, j, k, dist[MaxSize][MaxSize];
    for (i = 0; i < G->vertexNum; i++)
        for (j = 0; j < G->vertexNum; j++)
            dist[i][j] = G->edge[i][j];
}

经过v0

image.png
经过v1

image.png
经过v2

image.png

for (k = 0; k < G->vertexNum; k++) 
    for (i = 0; i < G->vertexNum; i++)       
        for (j = 0; j < G->vertexNum; j++)
            if (dist[i][k] + dist[k][j] < dist[i][j]) 
                dist[i][j] = dist[i][k] + dist[k][j];

Floyd算法-代码实现

void Floyd(MGraph *G)
{
    int i, j, k, dist[MaxSize][MaxSize];
    for (i = 0; i < G->vertexNum; i++)
        for (j = 0; j < G->vertexNum; j++)
            dist[i][j] = G->edge[i][j];
     for (k = 0; k < G->vertexNum; k++) 
        for (i = 0; i < G->vertexNum; i++)       
            for (j = 0; j < G->vertexNum; j++)
                if (dist[i][k] + dist[k][j] < dist[i][j]) 
                    dist[i][j] = dist[i][k] + dist[k][j];

Floyd算法性能分析

时间复杂度?
O(n3)