最短路Dijkstra算法的一些扩展问题

 
 

很早以前写过关于A*求k短路的文章,那时候还不明白为什么还可以把所有点重复的放入堆中,只知道那样求出来的就是对的。知其然不知其所以然是件容易引发伤痛的事啊,前天一次pku的比赛就得到了应验,因此下决心把这一类的问题要好好想一想。
 
搞了一天,总算有点成果,在此就总结一下这几类问题:

  1. 两点间的最短路的条数;
  2. 多关键字的极短路问题;
  3. 给定长度的路的条数;
  4. K短路及其条数;
  5. 标号法的一些看法;
  6. 程序设计与实现。

在此,先说明几个符号:
label 是每次出堆的一个标号;
struct label

{
  int vertex; // 该标号所代表的顶点
   int val; // 标号的值
};
phi(x):顶点x的标号,即源到该点的最短路
f(x):源到x的路径条数
S和T:分别是源和汇
问题1

当用顶点s来作更新时,设对某条边s->t长为v:
if phi(s)+v==phi(t) then f(t)+=f(s)
else if phi(t)>phi(s)+v then f(t)=f(s)
不用再多说了吧,这不是今天的重点,略过。
问题2,

多关键字的问题也是很具有实际意义的,就以双关键字为例子,其它的可以扩展。比如交通网络中的路一般都有收费和用时两个参量,在这种情况 下,就不存在一个最的定义,相应的,若用(cost,time)来表示一个标号,那么显然标号不再是一个全序而是偏序。在堆中比较两个标号可以采用第一、 第二关键字分别比较的方法,因此每次出堆的一定是一个极小的标号。由于每个顶点可以存在多个标号,因此对每个点维护一个标号的集合。如果把这个集合排序的 话,那么一定是按cost严格递增,同时按time严格递减。
问题3

,若要求的长度是L,设L*=phi(T),那么delta=T-T* ,即对图中的每个点来说,可以维持一个delta的冗余度,在这样的长度下都是有希望最后到达T的长度是L。这只是一个必要条件,能否进一步限定?设T到 图中任意点x的最短距离为lambda(x),那么对某个点x,只有标号同时满足:
1.label.val-phi(x)<=delta;
2.label.val+lambda(x)<=L 时才有希望。
可以发现,式子中的lambda就是用作A*的启发函数,因此我们把问题3就归结到了问题4,下面将一起处理。
问题4,这是本文的核心,我将详细说明。

我们知道A*对空间的要求是很高的,如果用扩展dijkstra的话则解收敛的更慢,因此更无法接受。如何优化扩展的顶点的数量就成了要亟待解决的关键问题。
定义: 将上面的delta我们称为冗余度,把每个点x分裂成独立的x+delta个顶点,那么这样形成的新图成为层次图。
用G’代表该层次图,那么G’的形态是怎样的呢?假想把原图G复制delta份按0,1,2顺序依次画出来,那么x+k所在的图就是第k层图。相应 扩展其他概念,用phi(x,k)表示从(S,0)到(x,k)的最短距离,f(x,k)表示到达(s,k)的最短路数量。对某条边(s->t, v)来说,若phi(s,k)+v==phi(t,k),即该边连接的点在同层,否则一定有phi(s,k)+v==phi(t,k’),k’> k,因此顺着这条边走就到达了下一层。
有了这个概念,不难知道我们要求的就是f(T,delta),即从(S,0)->(T,delta)的最短路的数量,化为我们已解决的问题1。但这还没完,层次图毕竟是个概念,在实现中要怎么解决呢?继续看下文。
要注意的是 (S,k),k>0是不存在的,这很容易理解。
问题5,标号法的实质其实可以归结为如下的定理:

对于一个求最大值的问题,如果能用标号法解决,当且仅当未知问题->未知问题的解决时间非负,即满足单调性。若要求解的数量,解决时间必须为正,即严格单调性。
这个性质很有意思,它只要求未知问题间的解决时间非负,因此联想到dijkstra算法,由于开始的时候S是已知问题,所以从S连出去的边是可以为负的,这在很多的书中都没有提到,因此很多人对dijkstra的理解也就停留在了机械记忆的阶段。
好了,
 
最后就是编程的问题了,我用代码来表示比较清晰。

Run dijkstra in the 0’th level,那么phi(x,0)就是已知的了。
while ( heap is not empty )
{
   Get a minimal label From min-heap
    For any edge along go outside this label , (s->t,v):
    length=label.val+v;
    k=label.val-phi(s,0);
    theta=length-phi(t,0);
    if ( theta <= delta )
   {
          f(t,theta)+=f(s,k);
          if (t,theta) is not in heap
             then Insert it into heap
    }
}
从代码中我们也看出,其实编程中并没用到phi(x,k),k>0,所以其实保留phi(x)就可以了。
最后计算下复杂度。|V’|<=delta*|V|,|E’|<=delta*(|E|+|V|^2),所以总复杂度O(delta*V^2*(lgV+lg(delta)),这实际上也是在以前的文章中遗留的用A*求K短路的复杂度上限。
好了,问题都解决了。可是仍然不够圆满,因为新问题又来了,如果delta比较大该怎么做呢?还是有办法,可以利用K短路算法解决。

最短路Dijkstra算法的一些扩展问题的更多相关文章

  1. 单源最短路dijkstra算法&&优化史

    一下午都在学最短路dijkstra算法,总算是优化到了我能达到的水平的最快水准,然后列举一下我的优化历史,顺便总结总结 最朴素算法: 邻接矩阵存边+贪心||dp思想,几乎纯暴力,luoguTLE+ML ...

  2. 单源最短路Dijkstra算法——matlab实现

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijk ...

  3. 单源最短路——dijkstra算法

    Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...

  4. ACM: HDU 2544 最短路-Dijkstra算法

    HDU 2544最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Descrip ...

  5. hdu2544 最短路 Dijkstra算法

    最短路(Dijkstra算法模板题) Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  6. 单源最短路(Dijkstra算法)

    #返回上一级 @Author: 张海拔 @Update: 2015-03-11 @Link: http://www.cnblogs.com/zhanghaiba/p/3514570.html Dijk ...

  7. POJ 3268 Silver Cow Party 最短路—dijkstra算法的优化。

    POJ 3268 Silver Cow Party Description One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbe ...

  8. POJ-3268-最短路(dijkstra算法)

    Silver Cow Party Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12494   Accepted: 5568 ...

  9. 【Aizu - 2249】Road Construction(最短路 Dijkstra算法)

    Road Construction Descriptions Mercer国王是ACM王国的王者.他的王国里有一个首都和一些城市.令人惊讶的是,现在王国没有道路.最近,他计划在首都和城市之间修建道路, ...

随机推荐

  1. 刷题总结——过河(NOIP2015)

    题目: 题目背景 NOIP2005提高组试题2. 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都 ...

  2. 【极角排序+双指针线性扫】2017多校训练七 HDU 6127 Hard challenge

    acm.hdu.edu.cn/showproblem.php?pid=6127 [题意] 给定平面直角坐标系中的n个点,这n个点每个点都有一个点权 这n个点两两可以连乘一条线段,定义每条线段的权值为线 ...

  3. [Hihocoder 1289] 403 Forbidden (微软2016校园招聘4月在线笔试)

    传送门 #1289 : 403 Forbidden 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Little Hi runs a web server. Someti ...

  4. 【黑科技】读写优化 orz bdd

    转自 bdd :http://www.cnblogs.com/kevince/p/3924688.html 读入优化: inline int read() { char ch; bool flag = ...

  5. bigdata related

    hive: http://lxw1234.com/archives/2015/07/413.htm 搜狗实验室数据集: https://www.sogou.com/labs/resource/list ...

  6. Python入门--5--列表

    python没有数组 蛋是有列表 列表里面可以有:整数,浮点数,字符串,对象 没有数组,没有数组,没有数组,不重要的也说三遍!! 一.创建列表 x = ['abc','sas','www']     ...

  7. python(3)- 常用快捷键及基础命令

  8. poj1149最大流经典构图神题

    题意:n个顾客依次来买猪,有n个猪房,每个顾客每次可以开若干个房子,买完时,店主可以调整这位顾客 开的猪房里的猪,共m个猪房,每个猪房有若干猪,求最多能卖多少猪. 构图思想:顾客有先后,每个人想要的猪 ...

  9. Effective Java P2 Creating and Destroying Objects

    This chapter concerns creating and destorying objects : when and how to create them, when and how to ...

  10. JDK内置工具jstack(Java Stack Trace)(转)

    1.介绍 jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的js ...