博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
图——图的Dijkstra法最短路径实现
阅读量:4352 次
发布时间:2019-06-07

本文共 3220 字,大约阅读时间需要 10 分钟。

1,最短路径的概念:

       1,从有向图中某一顶点(起始顶点)到达另一顶点(终止顶点)的路径中,其权值之和最小的路径;

      

2,问题的提法:

 

       1,给定一个带权有向图 G 与起始顶点 v,求从 v 到 G 中其它顶点的最短路径(每条边上都存在有意义的权值);

       2,Dijkstra 算法核心是通过已知最短路径寻找未知最短路径;

      

3,解决思路:

       1,Dijkstra 提出按路径长度的递增次序,逐步产生最短路径;

              1,首先求出长度最短的一条最短路径,再参照它求出长度次短的一条最短路径,依次类推,直到从起始顶点 v 到其它各顶点的最短路径全部求出为止;

       2,核心是通过递归的方式将从起始顶点到其他各顶点的最短路径全部求出来;

      

4,准备工作:

       1,辅助数组:Array<E> dist;

              1,dist[i] 表示当前从起始顶点 v0 到顶点 vi 的路径长度;

       2,初始设置:

              1,若从起始顶点 v0 到顶点 vi 有边:dist[i] 为该边上的权值;

              2,若从起始顶点 v0 到顶点 vi 无边:dist[i] 为无穷大;

             

5,Dijkstra 算法演示:

 

       1,由非空顶点集和边集这两个图的基本定义可知,集合在图的算法分析中的重要性,而集合在数据结构中常表现为数组;

       2,每次关注的是刚刚加入 S 集合的顶点到其他顶点的连接,通过刚刚求得的最短路径值来求出抵达其他顶点的可能的最短路径值,这就是核心;

         

6,Dijkstra 算法步骤:

 

7,Dijkstra 算法精髓:

       1,S 集合内的顶点是已经找到最短路径的顶点;

       2,v0 到 w 的最短路径只能通过 S 集内的顶点;

       3,dist[w] 可能改变:

 

             

8,如何记录最短路径上的各个顶点?

       1,定义辅助数组:

              1,Array<int> path;

                     1,path[i] 表示当前路径上的顶点 i 的前驱顶点;

                     2,初始化:path = {-1};

                     3,修改:

                           

                          

9,Dijkstra 算法流程图:

 

10,Dijkstra 最短路径算法:

1    /* 两个顶点之间最短路径,返回的数组表示两个最短路径上面的顶点 */ 2     SharedPointer< Array
> dijkstra(int i, int j, const E& LIMIT) // O(n*n) 3 { 4 LinkQueue
ret; // 保存最短路径上面的顶点 5 6 if( (0 <= i) && (i < vCount()) && (0 <= j) && (j < vCount()) ) 7 { 8 DynamicArray
dist(vCount()); // 用于存储路径值 9 DynamicArray
path(vCount()); // 用于存储当前结点的前驱结点10 DynamicArray
mark(vCount()); // 标记顶点是否进入 S 集合11 12 /* 原材料初始化 */13 for(int k=0; k
s;61 62 s.push(j); // 终止顶点 j 先放入栈中;63 64 /* 将从起始顶点 i 到终值顶点 j 的点先放到栈中去;前驱结点的访问方式、值当做位置;值就是前面的顶点,所以直接把值压入进栈*/65 for(int k=path[j]; k!=-1; k=path[k])66 {67 s.push(k);68 }69 70 /* path 中保存的顶点顺序是逆序的,通过栈中转下,调整过来; */71 while( s.size() > 0 )72 {73 ret.add(s.top());74 75 s.pop();76 }77 }78 else79 {80 THROW_EXCEPTION(InvalidParameterException, "Index
is invalid ...");81 }82 83 /* 最终最短路径经历顶点数至少有 2 个,否则 i 到 j 是不可达的,最多多少顶点是不知道的 */84 if( ret.length() < 2 )85 {86 THROW_EXCEPTION(ArithmeticException, "There is no path from i to j ...");87 }88 89 return toArray(ret); // 放到数组里面90 }

 

11,Dijkstra 最短路径算法测试代码:

1 #include 
2 #include "MatrixGraph.h" 3 #include "ListGraph.h" 4 5 using namespace std; 6 using namespace DTLib; 7 8 template< typename V, typename E > 9 Graph
& GraphEasy()10 {11    static MatrixGraph<4, V, E> g;12 13 g.setEdge(0, 1, 1);14 g.setEdge(0, 2, 3);15 g.setEdge(1, 2, 1);16 g.setEdge(1, 3, 4);17    g.setEdge(2, 3, 1);18 19 return g;20 }21 22 template< typename V, typename E >23 Graph
& GraphComplex()24 {25    static ListGraph
g(5);26 27 g.setEdge(0, 1, 10);28 g.setEdge(0, 3, 30);29 g.setEdge(0, 4, 100);30 g.setEdge(1, 2, 50);31 g.setEdge(2, 4, 10);32 g.setEdge(3, 2, 20);33    g.setEdge(3, 4, 60);34 35 return g;36 }37 38 int main()39 {40 Graph
& g = GraphComplex
();41    SharedPointer< Array
> p = g.dijkstra(0, 4, 65535);42 43 for(int i=0; i
length(); i++)44 {45 cout << (*p)[i] << " ";46    }47 48    cout << endl;49 50 return 0;51 }

 

12,小结:

       1,Dijkstra 最短路径算法是基于递推的思想完成的;

       2,起始顶点到其他各顶点的最短路径通过动态推导得到;

       3,未标记顶点的最短路径只能由已标记顶点计算得出;

       4,算法的最终结果是起始顶点到其它各顶点的最短路径;

转载于:https://www.cnblogs.com/dishengAndziyu/p/10926621.html

你可能感兴趣的文章
[转载] Activiti Tenant Id 字段释疑
查看>>
[Java 8] (8) Lambda表达式对递归的优化(上) - 使用尾递归 .
查看>>
SQL Server-聚焦移除Bookmark Lookup、RID Lookup、Key Lookup提高SQL查询性能
查看>>
最小权限的挑战
查看>>
jquery 视觉特效(水平滚动图片)
查看>>
SVG笔记
查看>>
go web framework gin group api 设计
查看>>
linux下使用dd命令写入镜像文件到u盘
查看>>
001---进程
查看>>
视频人脸检测——OpenCV版(三)
查看>>
php获取来访者在搜索引擎搜索某个关键词,进入网站
查看>>
物联网架构成长之路(8)-EMQ-Hook了解、连接Kafka发送消息
查看>>
2018-2019-1 20165234 20165236 实验二 固件程序设计
查看>>
IDEA的GUI连接数据库写入SQL语句的问题总结
查看>>
Xpath在选择器中正确,在代码中返回的是空列表问题
查看>>
leecode第一百九十八题(打家劫舍)
查看>>
【BZOJ 1233】 [Usaco2009Open]干草堆tower (单调队列优化DP)
查看>>
07-3. 数素数 (20)
查看>>
写一个欢迎页node统计接口Py脚本(邮件,附件)-py
查看>>
计算两个日期之间的天数
查看>>