[算法]任意两点间最短距离与路径Floyd-Warshall算法

[算法]任意两点间最短距离与路径Floyd-Warshall算法

以前就是觉得这Floyd算法很简单的,不就是三个循环嘛,但是那时候不知道这三个循环究竟是为何的,只是为了考研而把它背下来,不理解,只是觉得Floyd算法很简练,代码就如下几行。

其中,

d[i][j]记录两点间距离,

p[i][j]记录i -> j路径上第二个结点,其实就是第一个非开始结点的结点,

譬如上述图中,p[0][2]=1,因为0->1->2,p[0][1]=1,两点之间一次可达是最小距离的话就是终点。

由此通过p可以记录任意两点的最短路径。

void Floyd_Warshall(int d[maxSize][maxSize],int p[maxSize][maxSize], int n)

{

    int i, j, k;

    for(i = 0; i < n; ++i)

    {

        for(j = 0; j < n; ++j)

        {

            p[i][j] = j;

        }

    }

    for(k = 0; k < n; ++k)

    {

        for(i = 0; i < n; ++i)

        {

            for(j = 0; j < n; ++j)

            {

                if(d[i][k]+d[k][j] < d[i][j])

                {

                    d[i][j] = d[i][k]+d[k][j];//更新最短距离

                    p[i][j] = p[i][k];//更新下一跳的点

                }

            }

        }

    }

}

 

 在对动态规划有了更深一层了解之后,才想起原来这个Floyd算法是自底向上的动态规划算法

Dk(i,j)为从i到j的只以(1..k)集合中的节点为中间節点的最短路径的长度 ,它的状态转移方程

若i,j的最短路径经过k,则Dk(i,j)=Dk-1(i,k)+Dk-1(k,j)

若i,j的最短路径不经过k,则Dk(i,j)=Dk-1(i,j)

现在不知道最短路径是否经过k,我们可以通过比较上述两个大小,知道较小值就是当前最短距离,便可决定是否经过k,

最终Dk(i,j)取上述两种情况的最小值。则Dk(i,j)=min (Dk-1(i,j) , Dk-1(i,k)+Dk-1(k,j))

于是可以根据这转移方程得出自顶下上的动态规划算法,如此就是代码的实现。

 

 


本文基于知识共享署名-非商业性使用 3.0 许可协议进行许可。欢迎转载、演绎,但是必须保留本文的署名林羽飞扬,若需咨询,请给我发信

你可能感兴趣的:(floyd)