Floyd-Warshall 算法

Posted

技术标签:

【中文标题】Floyd-Warshall 算法【英文标题】:Floyd-Warshall algorithm 【发布时间】:2015-12-05 20:35:04 【问题描述】:

我的代码似乎有问题。对于最短路径,我得到了一些意想不到的值。我将结果与仅使用正距离的 Dijkstra 和 Bellman 算法进行了比较,因此问题不在于输入。此外,我首先将无限距离输入为零,然后转换它们(对角线除外)。任何反馈将不胜感激。

#include <iostream>
#include <limits>
#define infinity std::numeric_limits<int>::max()



void Warshall(int **Adj_Matrix, int vertices)

int i,j,k;

for(k = 0; k < vertices; k++)
    for(i = 0; i < vertices; i++)
        for(j = 0; j < vertices; j++)
            if(Adj_Matrix[i][j] > (Adj_Matrix[i][k] + Adj_Matrix[k][j]))
                   Adj_Matrix[i][j] = Adj_Matrix[i][k]+Adj_Matrix[k][j];       


int main()


int i,j,NumofVertices;
int **Adj_Matrix;
int *Cost_Row;

std::cout<<"Enter the number of vertices: ";
std::cin>>NumofVertices;

Adj_Matrix = new int*[NumofVertices];

for(i = 0;i < NumofVertices; i++)
    Adj_Matrix[i] = new int[NumofVertices];


std::cout<<"Enter the adjacency matrix"<<std::endl;
    for(i = 0; i < NumofVertices; i++)
        for(j = 0; j < NumofVertices; j++)
            std::cin>> Adj_Matrix[i][j];
            if (Adj_Matrix[i][j] == 0 && i != j)
            
                Adj_Matrix[i][j] = infinity;
            
    


Warshall(Adj_Matrix,NumofVertices);
for(i = 0; i < NumofVertices; i++)
    for(j = 0; j < NumofVertices; j++)
            std::cout<<"Shortest path between "<<i<<" and "<<j<<" is : ";
            if(Adj_Matrix[i][j]==infinity)
                    std::cout<<"INF"<<std::endl;
            else
                    std::cout<<Adj_Matrix[i][j]<<std::endl;
    


return 0;


【问题讨论】:

您确实意识到在您的算法中infinity + something 会给出一个负数?? Adj_Matrix[i][k] + Adj_Matrix[k][j] 表现出未定义的行为,通过整数溢出,如果任一权重恰好是 std::numeric_limits&lt;int&gt;::max()(在您的程序中也称为 infinity 【参考方案1】:

我在当前代码中看到的唯一问题是 ::

if(Adj_Matrix[i][j] > (Adj_Matrix[i][k] + Adj_Matrix[k][j]))

所以,如果Adj_Matrix[i][k]Adj_Matrix[k][j] 是无穷大,那么如果你尝试向它添加一些东西,那么它就是一个整数溢出,并且该值将是未定义的(主要是负数!)这将导致修改Adj_Matrix[i][j]的值!

为防止这种情况,您只需添加一个if 条件,如下所示::

for(k = 0; k < vertices; k++)
    for(i = 0; i < vertices; i++)
        for(j = 0; j < vertices; j++)
            if(Adj_Matrix[i][k] != infinty && Adj_Matrix[j][k] != infinity && Adj_Matrix[i][j] > (Adj_Matrix[i][k] + Adj_Matrix[k][j]))
                   Adj_Matrix[i][j] = Adj_Matrix[i][k]+Adj_Matrix[k][j];       

我相信这会成功的!

【讨论】:

以上是关于Floyd-Warshall 算法的主要内容,如果未能解决你的问题,请参考以下文章

Floyd-Warshall 算法的最小权重循环

Floyd-Warshall 算法

如何在 Floyd-Warshall 算法中输出最短路径?

Floyd-Warshall 算法是如何工作的,K 是啥?

多源最短路径--Floyd-Warshall算法

最短路径之Dijkstra算法和Floyd-Warshall算法