当前位置: 首页 > 知识库问答 >
问题:

Bellman-ford邻接矩阵不检测负循环的单源最短路径

田念
2023-03-14

我曾尝试实现Bellman-ford单源最短路径的邻接矩阵,但它并没有检测到负循环中的一个顶点

同样的算法适用于边缘列表,但在相邻矩阵中给出了误差

我的代码:

#include <iostream>
#include <climits>
#include <vector>
using namespace std;

#define INF INT_MAX
#define NINF INT_MIN

void shortestpath(int src, vector<vector<int>> &matrix){
    int N = matrix.size();
    vector<int> dist(N, INF);
    vector<int> prev(N, 0);

    dist[src] = 0;
    for(int k = 0; k < N-1; k++){
        for(int i = 0; i < N; i++){
            for(int j = 0; j < N; j++){
                if(dist[i] != INF && matrix[i][j] && dist[j] > (dist[i] + matrix[i][j]) ){
                    dist[j] = dist[i] + matrix[i][j];
                    prev[j] = i;
                }
            }
        }
    }

    // for(int i = 0; i < N; i++)
    //     if(i != src)
    //         cout << src << " - " << i << "\t" << dist[i] << endl;
    // cout << "\n\n";

    // to check if -ve cycles exist or not
    for(int k = 0; k < N-1; k++){
        for(int i = 0; i < N; i++){
            for(int j = 0; j < N; j++){
                if(matrix[i][j] && dist[j] > (dist[i] + matrix[i][j]) ){
                    dist[j] = NINF;
                    prev[j] = -1;
                }
            }
        }
    }

    for(int i = 0; i < N; i++)
        if(i != src)
            cout << src << " - " << i << "\t" << dist[i] << endl;
    return ;
}

// Driver function
int main(){
    int V = 8;
    vector<vector<int>> matrix(V, vector<int>(V, 0));
    matrix[0][1] = 1;
    matrix[1][2] = 1;
    matrix[2][4] = 1;
    matrix[4][3] = -3;
    matrix[3][2] = 1;
    matrix[1][5] = 4;
    matrix[1][6] = 4;
    matrix[5][6] = 5;
    matrix[6][7] = 4;
    matrix[5][7] = 3;

    shortestpath(0, matrix);

    return 0;
}
 

输出:

0 -> 1   =   1
0 -> 2   =  -2147483648
0 -> 3   =  -3
0 -> 4   =  -2147483648
0 -> 5   =  5
0 -> 6   =  5
0 -> 7   =  8

2时有一个-ve循环-

共有1个答案

乜建柏
2023-03-14

在第二个循环中,如果dist[i]已设置为INT\u MINmatrix[i][j]为负值,则dist[i]矩阵[i][j]可能通过整数溢出的方式表现出未指定的行为。实际上,求和会变成一个大的正数,然后条件dist[j]

 类似资料:
  • 我知道这有点难,但我正在学习普林斯顿大学的算法课程。我尝试使用Bellman-Ford算法来检测边加权有向图中的负圈。 完整的代码实现可从以下网址获得:BellmanFordSP。java和EdgeWeightedDirectedCycle。JAVA具体来说,我被困在这一点上: 这个条件表示什么:。为什么我们只在这个特定的条件下检查负循环?

  • 有了贝尔曼-福特的算法,稍有改变:在第7行,我们把

  • Dijkstra不能用于最长路径,因为它使用的属性是当前最短路径肯定比其他路径短。这是正确的,当然,假设没有负边缘权重。这个概念也是为什么最长路径在Dijkstra上不起作用的原因,因为当前最长的路径不能保证以后不会有另一个更长的路径取更大的值。 另一方面,贝尔曼福特提供了在较差的性能负权重的灵活性。这意味着,对于贝尔曼福特来说,它不像迪克斯特拉那样在同样贪婪的财产上工作。所以这就是为什么我很困惑

  • 实现图的最简单的方法之一是使用二维矩阵。在该矩阵实现中,每个行和列表示图中的顶点。存储在行 v 和列 w 的交叉点处的单元中的值表示是否存在从顶点 v 到顶点 w 的边。 当两个顶点通过边连接时,我们说它们是相邻的。 Figure 3 展示了 Figure 2 中的图的邻接矩阵。单元格中的值表示从顶点 v 到顶点 w 的边的权重。 Figure 3 邻接矩阵的优点是简单,对于小图,很容易看到哪些节

  • SameGame示例 让我们以一个SameGame板为例。 如果两个块有一个共同的边,则它们是相邻的。组是由至少两个块组成的集合,所有块都是相同类型的,并且每个块都与组的至少一个其他成员相邻。当鼠标悬停在作为组的一部分的块上时,整个组应在视觉上突出显示。 举个矩阵的例子: 鼠标悬停怎么找一套? 我想过递归,但老实说,我不知道该怎么做。BFS似乎是我可以做的事情,但对于这样一个“简单”的事情来说,它

  • 问题内容: 我对图和邻接矩阵感到困惑。我正在为 一个班级做作业,我有一个节点的文本文件和一个边的文本文件,我必须 阅读它们的每一个并将它们制成一个图,然后可以在该图上执行 操作,例如确定图是否为连接,找到最小的 生成树,遍历并找到路径。但是我之前从未使用过图形 ,并且整个过程让我很困惑,我想知道 是否有人可以帮助我解释其中的一些内容。 首先,我是否要自己建立一个图(也许有节点和边类?) ,然后从中