首页 > 编程语言 >最短路径Dijkstra算法

最短路径Dijkstra算法

时间:2022-11-29 22:15:14浏览次数:42  
标签:pq 路径 算法 最短 Dijkstra distTo 顶点 edgeTo

最短路径

最短路径的性质:

  • 路径是有向的
  • 权重不一定等价于距离,权重也可以指时间,花费或者其他
  • 并不是所有顶点都是可达的
  • 负权重会使得问题更复杂(Dijkstra算法不适用于这种情况)
  • 最短路径一般都是简单的,这里算法会忽略构成环的零权重边,找到的最短路径都不会有环
  • 最短路径不一定是唯一的
  • 可能存在平行边和自环

最短路径树:给出起点s,计算结果是一颗最短路径树(Shortest Path Tree SPT),它包含了顶点s到所有可达顶点的最短路径

数据结构:

  • 最短路径树中的边edgeTo[],edgeTo[v]表示s到v的最短路径中的最后一条边
  • 到达起点的距离distTo[],distTo[v]表示s到v的已知最短路径长度

Dijkstra 算法

取自<算法>第四版-算法4.9

该算法类似Prim及时算法


    private double[] distTo;          // distTo[v] = distance  of shortest s->v path
    private DirectedEdge[] edgeTo;    // edgeTo[v] = last edge on shortest s->v path
    private IndexMinPQ<Double> pq;	  // priority queue of vertices

	public DijkstraSP(EdgeWeightedDigraph G, int s) { 
		// 起点到各个顶点v的距离
        distTo = new double[G.V()];
        // 起点到各个顶点v最短路径中的最后一条边
        edgeTo = new DirectedEdge[G.V()];

        // 初始化起点s到各个顶点的距离为无穷最大值
        for (int v = 0; v < G.V(); v++) {
            distTo[v] = Double.POSITIVE_INFINITY;
        }
        distTo[s] = 0.0;

        // 从s到顶点v的权重为优先级
        pq = new IndexMinPQ<Double>(G.V());
        // s为起点
        pq.insert(s, distTo[s]);
        while (!pq.isEmpty()) {
            // 取出顶点v
            int v = pq.delMin();
            // 遍历顶点v的各个边
            for (DirectedEdge e : G.adj(v)) {
                relax(e);
            }
        }
	}

    // 松弛一个顶点,判断起点s到顶点w的最短路径是否是s -> v -> w
    private void relax(DirectedEdge e) {
        // 边e为从顶点v到顶点w的有向边
        int v = e.from(), w = e.to();
        // 如果s到w的距离大于s到v + v到w的距离,则更新该距离,并将顶点w存入优先级队列
        if (distTo[w] > distTo[v] + e.weight()) {
            distTo[w] = distTo[v] + e.weight();
            edgeTo[w] = e;
            // 如果队列中已存在顶点w,则需要更新s到顶点w的距离,也即是更新权重
            if (pq.contains(w)) {
                pq.decreaseKey(w, distTo[w]);
            } else {
                pq.insert(w, distTo[w]);
            }               
        }
    }

    // 判断起点s到顶点v是否可达
    public boolean hasPathTo(int v) {
        return distTo[v] < Double.POSITIVE_INFINITY;
    }

	// 获取起点s到顶点v的最短路径
    public Iterable<DirectedEdge> pathTo(int v) {
        if (!hasPathTo(v)) {
            return null;
        }
        Stack<DirectedEdge> path = new Stack<DirectedEdge>();
        for (DirectedEdge e = edgeTo[v]; e != null; e = edgeTo[e.from()]) {
            path.push(e);
        }
        return path;
    }

空间复杂度:V

时间复杂度:ElogV

给定两点s->t的最短路径:可使用Dijkstra算法并在优先队列中取到t之后终止搜索

任意顶点之间的最短路径:遍历各个顶点构造最短路径树,时间及空间复杂度均为EVlogV

加权无环图

加权无环图:加权有向图中不含有有向环的图

可在线性时间内解决加权无环图中的最短路径问题,比Dijkstra算法更快

  • 可在线性时间内解决单点最短路径问题
  • 能够处理负权重的边

待补充...

负权重的加权有向图

负权重的加权有向图:可能含有环也可能含有负权重的边的加权有向图

Bellman-Ford算法:时间复杂度EV,空间复杂度V

大佬自行研究去吧,我该curd去了

标签:pq,路径,算法,最短,Dijkstra,distTo,顶点,edgeTo
From: https://www.cnblogs.com/z-dk/p/16936859.html

相关文章

  • 【算法训练营day21】LeetCode530.二叉搜索树的最小绝对差 LeetCode501. 二叉搜索树中
    LeetCode530.二叉搜索树的最小绝对差题目链接:530.二叉搜索树的最小绝对差初次尝试利用二叉搜索树的性质:中序遍历的结果是有序递增数组,最后遍历该数组得到最小绝对差。c......
  • 双指针算法
    双指针算法大致格式如下:for(inti=0;i<n;i++){ while(j<i&&check(i,j))j++; //每道题目的具体逻辑}核心思想:for(inti=0;i<n;i++){ for(int......
  • 图解实例讲解JavaScript算法,让你彻底搞懂
    你好程序员,我们大多数人都害怕算法,并且从未开始学习它。但我们不应该害怕它。算法只是解决问题的步骤。今天让我们以简单和说明性的方式介绍主要算法。不要试图记住它们......
  • C#数据结构-七大查找算法
    阅读目录1.顺序查找2.二分查找3.插值查找4.斐波那契查找5.分块查找6.树表查找7.哈希查找下面所有的代码,都已经经过vs测试。1.顺序查找基本思想:顺序查找也称为......
  • 创建仿生算法来寻找大脑癫痫灶
    发作间期的尖峰。a)典型波形。b)在时间t=0时传感器上的颜色编码活动分布示例,对应于峰值。它显示了一个明确的偶极子模式,表明符号变化区域中的癫痫灶。莫斯科国立高等经......
  • 10.查找算法
    在java中,我们常用四种查找算法:  1.顺序查找(线性)  2.二分法/折半查找  3.插值查找  4.斐波那契查找1.线性查找. 2.二分查找算法二分查找:对一个进行二......
  • 【量化LDPC】基于量化技术的LDPC译码算法的研究与matlab仿真
    1.本LDPC采用的量化方案      改进方案如下所示:   是由一个统计范围得到的,但是在实际中,根据信道的不同,可能存在多种可能,这里,我们的考虑的方案是自适......
  • 【最通俗易懂】A*寻路算法C#实现
    A*算法其实也不复杂,首先有以下几个概念:开启的节点表(OpenList)存放着所有的待检测的节点(坐标),每次都会从其中寻找出符合某个条件的节点。关闭的节点表(ClosedList)存放着所有......
  • AES算法学习02:原理总结和实现(ECB)
    一原理介绍:其实AES就是对16byte(128bit)数据进行加密的过程。说白了就是把128位通过一系列的变化变成另一个128数据。   这里主要用到2个关键的东西。密钥(key)这个是绝......
  • 代码随想录算法训练营第十四天 | 理论基础 递归遍历 迭代遍历 统一迭代
    今日内容:●理论基础●递归遍历●迭代遍历●统一迭代详细布置理论基础需要了解二叉树的种类,存储方式,遍历方式以及二叉树的定义文章讲解:https://pro......