Shortest Path

原创 2016年06月01日 22:32:38

Prove Dijkstra Algorithm

单源最短路径问题的几个算法看过好多遍了,可是每次重看的时候,都不记得为什么要这么做,只是纯粹的记得要这么做而已。今天又翻到,又忘记了原理,终于郁闷了,下决心把自己的推理过程写上来,因为网上真的就还没搜索到完整的证明过程的,也算是做个贡献。当然,我不是Dijkstra,智慧天赋相差甚远,证明过程中难免存在错误纰漏,欢迎有人拍砖指正。

Dijkstra算法实际上求出了一个带权有向图中某一个顶点到其他所有顶点的最短路径,这里只考虑最简单的一种情况,即所有权值(‘weight’ or ‘distance’ or ‘cost’)都是正值(positive number)。

辅助证明的数据结构:

int w[n, n],初始化w[0,0]=0,其余为int.MaxValue(在这里表示无穷大,即不能到达)

bool d[n,n],初始化d[0,0]=true,其余为false,即S到其他点的最短距离尚未求出。

w和d中的第一个分量表示进行到算法的第几次搜索.

符号标记:

设图G(V,E)共有|V|=n个顶点,源点标记为S,序号为0,其余各顶点依次标记为V_1,V_2,…,V_(n-1),用w(S,V_i),i=1,2,…,n-1,来表示源点S到V_i点的权值,也就是距离。

设集合A为:A={V | w[S,V]已经是S至V的最短距离},也就是说,源点到集合A内的任意顶点之间的最短距离是已经求出的,称A内的顶点为已经访问过的顶点(visited vertices)。

设集合B为:B={V | w[S,V]是一中间值},也就是说,此时S至V的最短距离还是未知的,保存的只不过是一个中间值而已,至于中间值如何得出,后面会有说明。称B内的顶点为未访问的顶点(unvisited vertices),可见B是A的补集。

证明:

(I)首先考虑最简单的情况,找找思路。

由于现在只知道S到S的最短距离,也就是0,所以第一步只能考虑从S出发直接到达各点的距离(显然在这个时候考虑路径存在中间顶点没有意义,因为你不能确定S到这个中间顶点的最短路径)。得到S直达各点的w(S,V_i),i=1,2,…,n-1,与w[0,i]比较,w[1,i]保存小值。

这个时候,Dijkstra的做法是选出所有d[0,i],i=0…n-1,为false的对应的w[1,i],i=0…n-1,中的最小值w[1,k]并认为这就是源点S到目标顶点V_k的最短距离。这很好理解,因为假设S到V_k的最短距离是另外一条路径,则必然存在一个中间顶点,不妨设为V_u,u=0…n-1,则有w(S,V_u) + w(V_u, V_k) < w(S,V_k),那么必有w(S,V_u) < w(S,V_k),显然,这与w[1,k]是最小值矛盾,所以w[1,k]就是S到V_k的最短距离,此时把d[1,k]标记为true。

算法的中间值如何得出:

其实以上的叙述已经说明了中间值是如何得到的。设w[x,y]是当前刚确定的源点S到目标定点V_y的最短距离,其中x=0…n-1,y=0…n-1,对所有d[x,i],i=0…n-1,为false的点,更新w[x+1,i]为w[x,i]与(w[x,y]+w(V_y,V_i))的较小值。(I)里的w[x,y]就是w[0,0]。

(II)现在考虑一般情况

设已求得一个集合A,|A|=k,现在求S到第(k+1)个点(注意不一定是V_(k+1),这里的k只是A的基数而已)。

设w[k-1,u],u=0…n-1,是在集合A的基数为k时,所有未访问的w[k-1,i],i=0…n-1,保存的中间值中的最小值(也就是最后一个纳入集合A的顶点,k-1-0+1=k)。标记d[k-1,u]为true,对所有w[k,i],更新d[k-1,i]为false的w[k,i]的值,使其为w[k-1,i]与w[k-1,u]+w(V_u, V_i)的较小值,然后选出d[k,i]为false的所有w[k,i]的最小值w[k,p],p=0…n-1,即源点S到目标顶点p的最短距离,标记d[k,p]为true,继续这一过程,直到某一次求出的最小值为int.MaxValue(表示之后的点都不能到达)。

道理仍然是一样的,如果这个最小值w[k,p]不是源点S到顶点V_p的最短距离,那么设S经过顶点V_t然后到达V_p(V_t是这条路径的倒数第二个顶点)。V_t存在两种可能,要么属于集合A但不是顶点V_u,要么属于集合B。

(i)如果V_t属于A但不是顶点V_u,由于每一个中间值在每求出一个最短距离时都是比较过的,也就是说,在求出S到V_t的最短距离时,S->V_t->V_p的长度必然是和原来的S->V_p的路径长度比较过的,一定会保存下来,则不可能得到当前这个w[k,p],w[k,p]里保存的应该是S经过V_t到V_p的长度而不是S经过V_u到V_p的长度。

(ii)如果V_t属于B,不妨设这条路径为S->V_r->V_o->V_t->V_p,其中V_r属于A,V_o,V_t可以是同一点,也可以是不同点,但是他们都不属于A而是属于B,那么显然有S->V_r->V_o的长度小于S->V_r->V_o->V_t->V_p的长度小于w[k,p],即w[k,o] < w[k,p],与w[k,p]是最小值矛盾。

(iii) 如果路径为S->V_t->V_p且V_t属于B,那么显然S->V_t比S->V_p要近,也就是说,在选择下一个最小值的时候,应该选择w[s,t]而非w[s,p]。

所以,这样一个顶点V_t不存在,一般情况得证。

证毕。

Prove Floyd Algorithm

pending

版权声明:如果文中有任何问题或者值得讨论的地方,都可以在下方留言或者QQ526664687,欢迎交流!!!

matlab k shortest path

  • 2010年08月15日 17:59
  • 5KB
  • 下载

HDU3631Shortest Path(Floyd的巧妙应用)经典

Shortest Path Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

Shortest_Path

  • 2013年12月04日 19:52
  • 3KB
  • 下载

shortest path案例小程序

  • 2011年08月04日 11:34
  • 7KB
  • 下载

zoj How Many Shortest Path 网络流 不相交最短路条数

题目大意:求不相交最短路,最多能有多少条。 建图,求出能用于最短路的边,用这些边建网络流的图,这些边容量都为1。最大流即为最终的答案。 //#pragma comment(link...
  • ACMmaxx
  • ACMmaxx
  • 2014年03月05日 13:34
  • 391

一个Shortest path程序

  • 2011年08月04日 11:32
  • 64KB
  • 下载

HDU携程决赛最短路径的代价/USTC 1280 Finding Shortest Path 求最短路边+最小割

Program:
  • kk303
  • kk303
  • 2014年05月14日 21:55
  • 1267

Maximizing Lifetime for the Shortest path

  • 2014年03月28日 15:49
  • 423KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Shortest Path
举报原因:
原因补充:

(最多只允许输入30个字)