"《算法导论》之‘图’":单点最短路径(有向图)
也许最直观的图处理问题就是你常常需要使用某种地图软件或者导航系统来获取从一个地方到另一个地方的路径。我们立即可以得到与之对应的图模型:顶点对应交叉路口,边对应公路,边的权重对应该路段的成本(时间或距离)。如果有单行线,那就意味着还需要考虑加权有向图。在这个模型中,问题很容易就可以被归纳为:
找到一个顶点到达另一个顶点的成本最小的路径。
前言
单点最短路径指的就是从源点S到给定的目的顶点V的总权重最小的路径。
从源点S出发,到所有可达的顶点的路径构成了一棵最短路径树(Shortest Path Tree, SPT)。下边显示了从不同源点出发所构成的最短路径树:
本文用到的加权有向图如下:
Dijkstra
边的松驰
下图展示了两个边的松驰的操作。在第一个例子中,因为distTo[v] + weght(v, w) > distTo[w],所以认为边v->w应该失效;在第二个例子中,distTo[v] + weght(v, w) < distTo[w],所以认识从其他顶点到w比从v到w的路径要长,原其他顶点到w的路径应该失效,v->w有效。
通过这两个例子,我们知道,松驰操作的思想跟Prim算法的思想是很相似的。
Java代码:
private void relax(EdgeWeightedDigraph G, int v)
{
for (DirectedEdge e : G.adj(v))
{
int w = e.to();
if (distTo[w] > distTo[v] + e.weight())
{
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;
}
}
}
Dijkstra算法
在《算法》中给出的Java代码如下:
public class DijkstraSP
{
private DirectedEdge[] edgeTo;
private double[] distTo;
private IndexMinPQ<Double> pq;
public DijkstraSP(EdgeWeightedDigraph G, int s)
{
edgeTo = new DirectedEdge[G.V()];
distTo = new double[G.V()];
pq = new IndexMinPQ<Double>(G.V());
for (int v = 0; v < G.V(); v++)
distTo[v] = Double.POSITIVE_INFINITY;
distTo[s] = 0.0;
pq.insert(s, 0.0);
while (!pq.isEmpty())
relax(G, pq.delMin())
}
private void relax(EdgeWeightedDigraph G, int v)
{
for (DirectedEdge e : G.adj(v))
{
int w = e.to();
if (distTo[w] > distTo[v] + e.weight())
{
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;
if (pq.contains(w)) pq.change(w, distTo[w]);
else pq.insert(w, distTo[w]);
}
}
}
public double distTo(int v) // standard client query methods
public boolean hasPathTo(int v) // for SPT implementatations
public Iterable<Edge> pathTo(int v) // (See page 649.)
}
Dijkstra算法的轨迹如下:
具体代码见Github.
"《算法导论》之‘图’":单点最短路径(有向图)的更多相关文章
- 【算法导论】单源最短路径之Bellman-Ford算法
单源最短路径指的是从一个顶点到其它顶点的具有最小权值的路径.我们之前提到的广度优先搜索算法就是一种无权图上执行的最短路径算法,即在所有的边都具有单位权值的图的一种算法.单源最短路径算法可以解决图中任意 ...
- 【算法导论】单源最短路径之Dijkstra算法
Dijkstra算法解决了有向图上带正权值的单源最短路径问题,其运行时间要比Bellman-Ford算法低,但适用范围比Bellman-Ford算法窄. 迪杰斯特拉提出的按路径长度递增次序来产生源点到 ...
- 【算法导论】图的广度优先搜索遍历(BFS)
图的存储方法:邻接矩阵.邻接表 例如:有一个图如下所示(该图也作为程序的实例): 则上图用邻接矩阵可以表示为: 用邻接表可以表示如下: 邻接矩阵可以很容易的用二维数组表示,下面主要看看怎样构成邻接表: ...
- 【算法导论】图的深度优先搜索遍历(DFS)
关于图的存储在上一篇文章中已经讲述,在这里不在赘述.下面我们介绍图的深度优先搜索遍历(DFS). 深度优先搜索遍历实在访问了顶点vi后,访问vi的一个邻接点vj:访问vj之后,又访问vj的一个邻接点, ...
- "《算法导论》之‘图’":深度优先搜索、宽度优先搜索(无向图、有向图)
本文兼参考自<算法导论>及<算法>. 以前一直不能够理解深度优先搜索和广度优先搜索,总是很怕去碰它们,但经过阅读上边提到的两本书,豁然开朗,马上就能理解得更进一步. 下文将会用 ...
- 带权图的最短路径算法(Dijkstra)实现
一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...
- 算法导论——lec 10 图的基本算法及应用
搜索一个图是有序地沿着图的边訪问全部定点, 图的搜索算法能够使我们发现非常多图的结构信息, 图的搜索技术是图算法邻域的核心. 一. 图的两种计算机表示 1. 邻接表: 这样的方法表示稀疏图比較简洁紧凑 ...
- 图的最短路径---迪杰斯特拉(Dijkstra)算法浅析
什么是最短路径 在网图和非网图中,最短路径的含义是不一样的.对于非网图没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径. 对于网图,最短路径就是指两顶点之间经过的边上权值之和最 ...
- C++编程练习(11)----“图的最短路径问题“(Dijkstra算法、Floyd算法)
1.Dijkstra算法 求一个顶点到其它所有顶点的最短路径,是一种按路径长度递增的次序产生最短路径的算法. 算法思想: 按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的 ...
随机推荐
- ELK平台的搭建
ELK是指Elasticsearch + Logstash + Kibaba三个组件的组合.本文讲解一个基于日志文件的ELK平台的搭建过程,有关ELK的原理以及更多其他信息,会在接下来的文章中继续研究 ...
- Android 如何监听输入法关闭事件
假设有如下界面(输入法的上面的输入区域是用Dialog实现的) 要求当输入法关闭的时候,Dialog也一起关闭,这样用户就不需要返回两次了. 网上找了很多资料都没有很好的解决这个问题,输入法是第三方程 ...
- Android必知必会-带列表的地图POI周边搜索
如果移动端访问不佳,请尝试–> Github版 2016-08-22 更新 注意:在 Activity 代码中的onPoiSearched(PoiResult result, int rCode ...
- 【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态
一. Objective-C 方法详解 1. 方法属性 (1) OC 方法传参机制 Object-C 方法传参机制 : OC 中得参数传递都是值传递, 传入参数的是参数的副本; -- 基本类型 (值传 ...
- picasso图片缓存框架
picasso是Square公司开源的一个Android图形缓存库,地址http://square.github.io/picasso/,可以实现图片下载和缓存功能. picasso使用简单,如下 [ ...
- 高通8x12平台开机画面制作工具
你可能在网上看到很到关于手动更换手机开机图片的文章,想想自己的开机画面是小两口,好基友的照片多么个性啊.但是你有没有发现,网上下载的什么"一键生成"之类的,在你的手机上不能用啊,( ...
- scala学习笔记2(类,继承,抽象类)
class Person{ // _ 是占位符; var name : String = _ val age : Int = 27 // private[this] 定义的内容无法外部使用,起到保护作 ...
- [C++学习历程]中级部分 OpenGL第一个例子实现
作者:sushengmiyan 本文地址:http://blog.csdn.net/sushengmiyan/article/details/21488231 环境:VS2010 准备工作: 1.下载 ...
- 编译Android 4.4.2源码
在之前的文章中,和大家分享了在天朝下下载android 4.4.2源码的过程(详见下载android4.4.2源码全过程(附已下载的源码)),现在写下编译的笔记. 虽然在android doc中,有提 ...
- 如何优化MySQL insert性能
对于一些数据量较大的系统,面临的问题除了是查询效率低下,还有一个很重要的问题就是插入时间长.我们就有一个业务系统,每天的数据导入需要4-5个钟.这种费时的操作其实是很有风险的,假设程序出了问题,想重跑 ...