最短路径

1. 最短路径定义以及性质

定义:

在一副加权有向图中,从顶点s到顶点t的最短路径是所有从顶点s到顶点t的路径中总权重最小的那条路径。

性质:

  1. 路径具有方向性。
  2. 权重不一定等于距离。权重可以是距离、时间、花费等内容,权重最小指的是成本最低。
  3. 只考虑连通图。一副图中并不是所有的顶点都是可达的,如果s和t不可达,那么它们之间也就不存在最短路径,所以只考虑连通图。
  4. 最短路径不一定是唯一的。从一个顶点到达另外一个顶点的权重最小的路径可能会有很多条,所以只需要找出一条即可。

最短路径树:

给定一副加权有向图和一个顶点s,以s为起点的一棵最短路径树是图的一副子图,它包含顶点s以及从s可达的所有顶点。这棵有向树的根结点为s,树的每条路径都是有向图中的一条最短路径。

2. 最短路径树API设计

计算最短路径树的经典算法是dijstra算法

类名 DijkstraSP
构造方法 public DijkstraSP(EdgeWeightedDigraph G, int s):根据一副加权有向图G和顶点s,创建一个计算顶点为s的最短路径树对象
成员方法 1.private void relax(EdgeWeightedDigraph G, int v):松弛图G中的顶点v
2.public double distTo(int v):获取从顶点s到顶点v的最短路径的总权重
3.public boolean hasPathTo(int v):判断从顶点s到顶点v是否可达
4.public Queue pathTo(int v):查询从起点s到顶点v的最短路径中所有的边
成员变量 1.private DirectedEdge[] edgeTo: 索引代表顶点,值表示从顶点s到当前顶点的最短路径上的最后一条边(也就是最短路径中的连接上一个顶点的边)
2.private double[] distTo: 索引代表顶点,值从顶点s到当前顶点的最短路径的总权重
3.private IndexMinPriorityQueue pq:存放树中顶点与非树中顶点之间的有效横切边

3. 松弛技术

松弛这个词来源于生活:一条橡皮筋沿着两个顶点的某条路径紧紧展开,如果这两个顶点之间的路径不止一条,还有存在更短的路径,那么把皮筋转移到更短的路径上,皮筋就可以放松了。

松弛这种简单的原理刚好可以用来计算最短路径树。

在API中,需要用到两个成员变量edgeTo和distTo,分别存储边和权重。一开始给定一幅图G和顶点s,我们只知道图的边以及这些边的权重,其他的一无所知,此时初始化顶点s到顶点s的最短路径的总权重disTo[s]=0;顶点s到其他顶点的总权重默认为无穷大,随着算法的执行,不断的使用松弛技术处理图的边和顶点,并按一定的条件更新edgeTo和distTo中的数据,最终就可以得到最短路劲树。

边的松弛:

顶点的松弛是基于边的松弛完成的,只需要把某个顶点指出的所有边松弛,那么该顶点就松弛完毕。例如要松弛顶点v,只需要遍历v的邻接表,把每一条边都松弛,那么顶点v就松弛了。

如果把起点设置为顶点0,那么找出起点0到顶点6的最短路径0->2->7>3->6的过程如下:

4.最短路径(Dijstra算法)实现

Disjstra算法的实现和Prim算法很类似,构造最短路径树的每一步都是向这棵树中添加一条新的边,而这条新的边是有效横切边pq队列中的权重最小的边

/*** 最短路径(dijkstra算法)*/
public class DijkstraSP {// 索引代表顶点,值表示从顶点s到当前顶点的最短路径上的最后一条边private DirectedEdge[] edgeTo;// 索引代表顶点,值从顶点s到当前顶点的最短路径的总权重private double[] distTo;// 存放树中顶点与非树中顶点之间的有效横切边private IndexMinPriorityQueue<Double> pq;// 根据一副加权有向图G和顶点s,创建一个计算顶点为s的最短路径树对象public DijkstraSP(EdgeWeightedDigraph G, int s) {// 初始化edgeTothis.edgeTo = new DirectedEdge[G.V()];// 初始化distTo,并且初始化数组中的内容为无穷大,无穷大即表示不存在这样的边this.distTo = new double[G.V()];for (int i = 0; i < distTo.length; i++) {distTo[i] = Double.POSITIVE_INFINITY;}// 初始化有效横切边队列this.pq = new IndexMinPriorityQueue<Double>(G.V());// 默认让顶点s进入队列,但s为最短路径树的根结点,所以初始化数组distTo为0.0distTo[s] = 0.0;pq.insert(s, 0.0);// 遍历有效横切边队列while (!pq.isEmpty()) {// 松弛图G中的顶点relax(G, pq.delMin());}}// 松弛图G中的顶点vprivate void relax(EdgeWeightedDigraph G, int v) {// 松弛顶点v就是松弛顶点v邻接表中的每一条边,遍历邻接表for (DirectedEdge e : G.adj(v)) {// 获取边e的终点int w = e.to();// 判断起点s到w的总权重与s经过v到w的总权重,如果大于则修正数据if (distTo[w] > distTo[v] + e.weight()) {// 修改s->w的路径edgeTo[w] = e;// 修改s到w的总权重distTo[w] = distTo[v] + e.weight();// 如果顶点w已经存在于优先队列pq中,则重置顶点w的权重if (pq.contains(w)) {pq.changeItem(w, distTo[w]);} else {// 如果顶点w没有出现在优先队列pq中,则把顶点w及其权重加入到pq中pq.insert(w, distTo[w]);}}}}// 获取从顶点s到顶点v的最短路径的总权重public double distTo(int v) {return distTo[v];}// 判断从顶点s到顶点v是否可达public boolean hasPathTo(int v) {return distTo[v] < Double.POSITIVE_INFINITY;}// 查询从起点s到顶点v的最短路径中所有的边public Queue<DirectedEdge> pathTo(int v) {// 如果顶点s到v不可达,则返回nullif (!hasPathTo(v)) {return null;}// 创建队列Queue保存最短路径的边Queue<DirectedEdge> edges = new Queue<>();// 从顶点v开始,逆向寻找,一直找到顶点s为止,而起点s为最短路劲树的根结点,所以 edgeTo[s]=null;DirectedEdge e = null;while (true) {e = edgeTo[v];if (e == null) {break;}edges.enqueue(e);v = e.from();}return edges;}
}

最短路径(加权有向图)相关推荐

  1. 数据结构之图:加权有向图与dijkstra算法找到最短路径,Python——28

    加权有向图与dijkstra算法找到最短路径 加权有向图的构造 最短路径问题与最短路径树 最短路径问题(The shortest path problem)定义 最短路径可以是时间花费最短,也可以是距 ...

  2. 【力扣】787. K 站中转内最便宜的航班加权——有向图最短路径

    前言 我感觉这题比较有代表性,所以记录一下,这题是加权有向图中求最短路径的问题. 题目 787. K 站中转内最便宜的航班 动态规划 假设有一条路径是[src, i, ..., j, dst],解法一 ...

  3. 最短路径算法---有向图

    最短路径算法---有向图. 最短路算法 最常用的最短路算法是Dijkstra算法.A*算法.SPFA算法.Bellman-Ford算法和Floyd-Warshall算法,我们这里重点介绍并实现Dijk ...

  4. 787. K 站中转内最便宜的航班(加权有向图的最短路径)

    题目:787. K 站中转内最便宜的航班 两种方法: 方法一: 思路: 加权图的最短路径 1. 首先将航线转化为字典形式存储.(当前城市–下一城市–费用) 2. 建一个双向队列,元素为元组形式.(当前 ...

  5. java数据结构代码(全)

    java数据结构 排序 ^运算: 找一个单数 找两个个单数 对数器 冒泡排序 选择排序 插入排序 希尔排序 快速排序 桶排序 基数排序 归并排序 基于归并排序的小数和 堆排序 二分 查找极小值 稀疏数 ...

  6. 几大最短路径算法比较

    用于解决最短路径问题的算法被称做"最短路径算法",有时被简称作"路径算法".最常用的路径算法有: Dijkstra算法.A*算法.SPFA算法.Bellman- ...

  7. 算法导论之每对顶点间的最短路径

    从单源顶点最短路径到每对顶点间最短路径,求解的问题从一个点扩展到所有点,描述如下:给定一个加权有向图G=(V,E),其加权函数w:E->R为边到实数权值的映射,对于每对顶点u,v∈V,找出从u到 ...

  8. C语言程序设计实验最短路径,7最短路径C语言程序设计.pdf

    最短路径 旅行家的困扰 第4章 图结构 解放军理工大学 旅行家的困扰 新 疆 特 克 斯 县 " 八 卦 城 " 第4章 图结构 解放军理工大学 旅行家的困扰 特克斯县 怎么样帮 ...

  9. 几个最短路径算法Floyd、Dijkstra、Bellman-Ford、SPFA的比较

        几大最短路径算法比较 转自:http://blog.csdn.net/v_july_v/article/details/6181485 几个最短路径算法的比较: Floyd        求多 ...

最新文章

  1. leetcode--删除排序数组中的重复项--python
  2. 在Android中,如何以编程方式在dp中设置边距?
  3. 电子书推荐--《Python灰帽子》,python黑客编程
  4. 【Matlab】方差是偏离均值的程度,那偏离中位数的程度怎么算呢?
  5. sonarqube执行命令遇上的小问题
  6. 这6部超经典的物理电影,居然还有人没有看过?
  7. SpringCloud工作笔记052---各种数据库在java中的连接配置_以及连接驱动
  8. 破旧立新 “云”称霸
  9. Elasticsearch高级查询2:ES 高级查询
  10. 常用User-Agent大全 -《狗嗨默示录》-
  11. 10-Python-mapfilter
  12. ai老师人工智能培训老师计算机视觉老师叶梓:计算机视觉领域的自监督学习模型——MAE-12
  13. 整数规划(数学+软件)【原创】
  14. python做excel表格合并_Python实战:合并 Excel 表格
  15. 拿下Facebook黑客杯四冠王!与Jeff Dean相提并论...ACM竞赛之神的传奇前半生
  16. ubuntu下定时清理文件
  17. Golang 调用MySQL存储过程
  18. 一年卖出1500万支的钟薛高,正在通过企业微信和顾客“社交”
  19. 4g网络什么时候淘汰_5G时代来临后,4G真的会被淘汰吗,简单说一下
  20. 关于微信小程序(应用号)的全部看法[转]

热门文章

  1. 信息学奥赛一本通-2069:【例2.12 】糖果游戏
  2. excel提取单元格内特定字符(字/词)前(后)的内容
  3. 利用useRef hooks 解决 定时器关闭不到的问题
  4. 二进制安全:ptmalloc内存管理机制与堆块chunk源码分析
  5. 有些MP4只有音频没有视频的解决办法
  6. [HEOI 2013 day2] 钙铁锌硒维生素 (线性代数,二分图匹配)
  7. 【C/C++学习】之STL详解
  8. ISIC2018比赛经验分享
  9. html改游戏聊天字体颜色,html点击按钮改变字体颜色怎么实现
  10. Python——库docx(四)12.25