bellman_ford算法与dijkstra为什么dijkstra算法不能计算带有负权边图

简介: bellman_ford算法与dijkstra为什么dijkstra算法不能计算带有负权边图

应用场景:带有负权边的图

为什么dijkstra算法不能计算带有负权边图

答:

dijkstra是一拳头买卖,一条边就经过一次,如果有负权边显然如果遍历多次这条边,最小值绝s对会更小。

所以bellman_ford算法大多的应用场景是在经过的边数有限制的情况下(能多次经过负权边但是有次数限制)

dijkstra算法(简介):

思路:

从源点开始(初始化为距离为0的那个点)也是自己确定的最小距离点

循环n(顶点数)次每一次确定一个距离最小值点,再用最小值点更新孩子节点,循环n次确定n个最小值点

通过点来更新其孩子(边只走一次)

bellman_ford算法

思路:

遍历n次,每次遍历所有的边,然后以父节点更新其出边(孩子节点)

遍历所有的边所以会遍历某个点的所有的入边,根据dist[i] + w[i] 和dist[x]该点的值]递推,即可得到最短距离

遍历n次所有的边,可以多次经过统一条边(可计算最大经过边数的最短路径(当有负权环的时候必须限定最大经理经历边数不然最小距离为负无穷))

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
    static int N = 510;
    static int M = 100010;
    static int n;//总点数
    static int m;//总边数
    static int[] dist = new int[N];//从1到点到n号点的距离
    static Node[] list = new Node[M];//结构体
    static int INF = 500000000 + 5000000;
    public static void bellman_ford()
    {
        Arrays.fill(dist, INF);
        dist[1] = 0;
        //最长可能的最短路径不会超过n-1条边  循环n - 1次也就是最多经过n - 1条边
        for(int i = 0;i < n - 1;i++)
        {
            for(int j = 0;j < m;j++)
            {
                Node node = list[j];
                int a = node.a;
                int b = node.b;
                int c = node.c;
                dist[b] = Math.min(dist[b], dist[a] + c);
            }
        }
        if(dist[n] >= 500000000) System.out.println("-1");
        else System.out.println(dist[n]);
    }
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] str1 = reader.readLine().split(" ");
        n = Integer.parseInt(str1[0]);
        m = Integer.parseInt(str1[1]);
        for(int i = 0;i < m;i++)
        {
            String[] str2 = reader.readLine().split(" ");
            int a = Integer.parseInt(str2[0]);
            int b = Integer.parseInt(str2[1]);
            int c = Integer.parseInt(str2[2]);
            list[i] = new Node(a,b,c);
        }
        bellman_ford();
    }
}
class Node
{
    int a, b, c;
    public Node(int a,int b,int c)
    {
        this.a = a;
        this.b = b;
        this.c = c;
    }
}

增加功能检测负权回路(不存在最短路径)

for (int i = 0; i < n; i++) {
    int u = edges[i].source;
    int v = edges[i].destination;
    int w = edges[i].weight;            //经过n条边,如果可以更新毕然存在负权回路
    if (distance[u] != Integer.MAX_VALUE && distance[u] + w < distance[v]) {
        System.out.println("图中包含负权回路");
        return;
    }
}
目录
相关文章
|
8天前
|
算法 C++
如何精确计算出一个算法的CPU运行时间?
如何精确计算出一个算法的CPU运行时间?
|
1月前
|
算法 数据可视化 数据安全/隐私保护
基于LK光流提取算法的图像序列晃动程度计算matlab仿真
该算法基于Lucas-Kanade光流方法,用于计算图像序列的晃动程度。通过计算相邻帧间的光流场并定义晃动程度指标(如RMS),可量化图像晃动。此版本适用于Matlab 2022a,提供详细中文注释与操作视频。完整代码无水印。
|
2月前
|
机器学习/深度学习 算法 Java
算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法
这篇文章介绍了基于贪婪技术思想的Prim算法和Dijkstra算法,包括它们的伪代码描述、Java源代码实现、时间效率分析,并展示了算法的测试用例结果,使读者对贪婪技术及其应用有了更深入的理解。
算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法
|
2月前
|
算法 Go Python
[算法]计算斐波拉契数列
[算法]计算斐波拉契数列
|
2月前
|
算法
路径规划算法 - 求解最短路径 - Dijkstra(迪杰斯特拉)算法
路径规划算法 - 求解最短路径 - Dijkstra(迪杰斯特拉)算法
44 0
|
2月前
|
算法
计算空间物体包围球的两种算法实现
计算空间物体包围球的两种算法实现
40 0
|
3月前
|
算法
基于Dijkstra算法的最优行驶路线搜索matlab仿真,以实际城市复杂路线为例进行测试
使用MATLAB2022a实现的Dijkstra算法在城市地图上搜索最优行驶路线的仿真。用户通过鼠标点击设定起点和终点,算法规划路径并显示长度。测试显示,尽管在某些复杂情况下计算路径可能与实际有偏差,但多数场景下Dijkstra算法能找到接近最短路径。核心代码包括图的显示、用户交互及Dijkstra算法实现。算法基于图论,不断更新未访问节点的最短路径。测试结果证明其在简单路线及多数复杂城市路况下表现良好,但在交通拥堵等特殊情况下需结合其他数据提升准确性。
|
3月前
|
资源调度 算法 定位技术
|
4月前
|
机器学习/深度学习 算法
**反向传播算法**在多层神经网络训练中至关重要,它包括**前向传播**、**计算损失**、**反向传播误差**和**权重更新**。
【6月更文挑战第28天】**反向传播算法**在多层神经网络训练中至关重要,它包括**前向传播**、**计算损失**、**反向传播误差**和**权重更新**。数据从输入层流经隐藏层到输出层,计算预测值。接着,比较预测与真实值计算损失。然后,从输出层开始,利用链式法则反向计算误差和梯度,更新权重以减小损失。此过程迭代进行,直到损失收敛或达到训练次数,优化模型性能。反向传播实现了自动微分,使模型能适应训练数据并泛化到新数据。
57 2
|
4月前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
下一篇
无影云桌面