最短路径算法----Dijkstra (转)
Dijkstra算法的核心思想是贪心策略+动态规划
算法流程:
在以下说明中,s为源,w[u,v]为点u和v之间的边的长度,结果保存在dis[]
初始化:源的距离dis[s]设为0,其他的点距离设为无穷大(实际程序里设成-1了),同时把所有的点的状态设为没有扩展过。
循环n-1次:
- 在没有扩展过的点中取一距离最小的点u,并将其状态设为已扩展。
- 对于每个与u相邻的点v,执行Relax(u,v),也就是说,如果dis[u]+map[u,v]<dis[v],那么把dis[v]更新成更短的距离dis[u]+w[u,v]。此时到点v的最短路径上,前一个节点即为u。
- 结束。此时对于任意的u,dis[u]就是s到u的距离。
wiki上有个很好的图,可以帮助理解算法过程:
测试数据来自清华的紫皮算法书,如下:
迭代过程如下:
迭代 |
S |
U |
dis[2] |
dis[3] |
dis[4] |
dis[5] |
初始 |
{1} |
--- |
10 |
-1 |
30 |
100 |
1 |
{1,2} |
2 |
10 |
60 |
30 |
100 |
2 |
{1,2,4} |
4 |
10 |
50 |
30 |
90 |
3 |
{1,2,4,3} |
3 |
10 |
50 |
30 |
60 |
4 |
{1,2,4,3,5} |
5 |
10 |
50 |
30 |
60 |
看上面的两个图,基本就能把Dijkstra算法的具体过程了解清楚。
算法正确性证明可以看Wiki和CLRS。
程序如下(测试数据就是上面的,输出了6个结果):
int dijk(int s, int e);函数返回从s到e的最短路。
1 #include <stdio.h> 2 #include <limits.h> 3 #include <string.h> 4 5 const int n = 6; 6 int map[n][n]; 7 8 int dijk(int s, int e) 9 { 10 int dis[n]; 11 int used[n] = {0}; 12 int min, next; 13 memset(dis, 255, sizeof(dis));//把所有未更新的dis[]设置成-1 14 15 dis[s] = 0; //从s开始 16 17 for (int i=1; i<n; ++i) 18 { 19 min = INT_MAX; 20 for (int j=1; j<n; ++j) 21 { 22 if (!used[j] && dis[j]!=-1 && dis[j]<min) 23 { 24 min = dis[j]; 25 next = j; 26 } 27 } 28 if (min != INT_MAX) 29 { 30 used[next] = 1; 31 for (int j=1; j<n; ++j) 32 { 33 if (!used[j] && map[next][j]!=-1 && 34 (dis[j]>map[next][j]+dis[next] || dis[j]==-1)) 35 { 36 dis[j] = map[next][j] + dis[next]; 37 } 38 } 39 } 40 } 41 return dis[e]; 42 } 43 44 45 int main() 46 { 47 for (int i=1; i<n; ++i) 48 { 49 for (int j=1; j<n; ++j) 50 { 51 map[i][j] = -1; 52 } 53 } 54 55 map[1][2] = 10; 56 map[1][4] = 30; 57 map[1][5] = 100; 58 map[2][3] = 50; 59 map[3][5] = 10; 60 map[4][3] = 20; 61 map[4][5] = 60; 62 63 printf("%d %d %d %d %d %d\n", dijk(1, 5), dijk(2, 3), dijk(1, 5), dijk(4, 5), dijk(1, 2), dijk(2, 4)); 64 65 66 return 0; 67 }
1 /*Dijkstra求单源最短路径 2010.8.26*/ 2 3 #include <iostream> 4 #include<stack> 5 #define M 100 6 #define N 100 7 usingnamespace std; 8 9 typedef struct node 10 { 11 int matrix[N][M]; //邻接矩阵 12 int n; //顶点数 13 int e; //边数 14 }MGraph; 15 16 void DijkstraPath(MGraph g,int*dist,int*path,int v0) //v0表示源顶点 17 { 18 int i,j,k; 19 bool*visited=(bool*)malloc(sizeof(bool)*g.n); 20 for(i=0;i<g.n;i++) //初始化 21 { 22 if(g.matrix[v0][i]>0&&i!=v0) 23 { 24 dist[i]=g.matrix[v0][i]; 25 path[i]=v0; //path记录最短路径上从v0到i的前一个顶点 26 } 27 else 28 { 29 dist[i]=INT_MAX; //若i不与v0直接相邻,则权值置为无穷大 30 path[i]=-1; 31 } 32 visited[i]=false; 33 path[v0]=v0; 34 dist[v0]=0; 35 } 36 visited[v0]=true; 37 for(i=1;i<g.n;i++) //循环扩展n-1次 38 { 39 int min=INT_MAX; 40 int u; 41 for(j=0;j<g.n;j++) //寻找未被扩展的权值最小的顶点 42 { 43 if(visited[j]==false&&dist[j]<min) 44 { 45 min=dist[j]; 46 u=j; 47 } 48 } 49 visited[u]=true; 50 for(k=0;k<g.n;k++) //更新dist数组的值和路径的值 51 { 52 if(visited[k]==false&&g.matrix[u][k]>0&&min+g.matrix[u][k]<dist[k]) 53 { 54 dist[k]=min+g.matrix[u][k]; 55 path[k]=u; 56 } 57 } 58 } 59 } 60 61 void showPath(int*path,int v,int v0) //打印最短路径上的各个顶点 62 { 63 stack<int> s; 64 int u=v; 65 while(v!=v0) 66 { 67 s.push(v); 68 v=path[v]; 69 } 70 s.push(v); 71 while(!s.empty()) 72 { 73 cout<<s.top()<<""; 74 s.pop(); 75 } 76 } 77 78 int main(int argc, char*argv[]) 79 { 80 int n,e; //表示输入的顶点数和边数 81 while(cin>>e>>n&&e!=0) 82 { 83 int i,j; 84 int s,t,w; //表示存在一条边s->t,q权值为w 85 MGraph g; 86 int v0; 87 int*dist=(int*)malloc(sizeof(int)*n); 88 int*path=(int*)malloc(sizeof(int)*n); 89 for(i=0;i<N;i++) 90 for(j=0;j<M;j++) 91 g.matrix[i][j]=0; 92 g.n=n; 93 g.e=e; 94 for(i=0;i<e;i++) 95 { 96 cin>>s>>t>>w; 97 g.matrix[s][t]=w; 98 } 99 cin>>v0; //输入源顶点 100 DijkstraPath(g,dist,path,v0); 101 for(i=0;i<n;i++) 102 { 103 if(i!=v0) 104 { 105 showPath(path,i,v0); 106 cout<<dist[i]<<endl; 107 } 108 } 109 } 110 return0; 111 }
参考资料:
Wikipedia:http://en.wikipedia.org/wiki/Dijkstra's_algorithm
Nocow:http://www.nocow.cn/index.php/Dijkstra%E7%AE%97%E6%B3%95
CLRS
《算法设计与分析》
(转)http://www.cnblogs.com/rootjie/archive/2012/05/15/2501317.html
最短路径算法----Dijkstra (转)相关推荐
- 计算机网络最短路径路由选择,最短路径算法Dijkstra算法在路由选择中的应用.pdf...
最短路径算法Dijkstra算法在路由选择中的应用.pdf 计算机与网络 江苏联合职业技术学院徐州机电工程分院 王恒青 江苏联合职业技术学院徐州生物工程分院 宋如敏 [摘要]本文介绍了路由算法的设计目 ...
- [转]最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现
最短路径算法-Dijkstra(迪杰斯特拉)算法分析与实现(C/C++) Dijkstra算法 ----------- 最后更新时间:2011.9.25 ----------- Dijkstra(迪杰 ...
- 最短路径算法——Dijkstra,Bellman-Ford,Floyd-Warshall,Johnson,无一幸免
文章出自:http://dsqiu.iteye.com/blog/1689163 最短路径算法--Dijkstra,Bellman-Ford,Floyd-Warshall,Johnson,无一幸免 本 ...
- 最短路径算法——Dijkstra and Floyd算法
一. 前言: 这个古老的算法应该耳熟能详了吧,但是我自从从学校出来到现在,最短路径算法都没有实际运用过,最近在一个GIS项目中总算用到了,于是乎把教材重温了下,同时查阅了网上很多的资料 ...
- 图论基础知识--最小生成树算法kruskal(克鲁斯克尔)和普里姆算法(Prim算法);最短路径算法Dijkstra(迪杰斯特拉)和Floyd(弗洛伊德)
一.基础知识 有向图 无向图 以无向图为例: 邻接矩阵: 度矩阵(对角矩阵): 二.最小生成树 应用:将网络顶点看着城市,边看着城市之间通讯网,边的权重看着成本,根据最小生成树可以构建城市之间 ...
- 带权图的最短路径算法(Dijkstra)实现
一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...
- 单源最短路径算法—Dijkstra算法(详细介绍)
一.算法简介 迪杰斯特拉算法(Dijkstra),由荷兰计算机科学家艾兹赫尔·戴克斯特拉在1956年提出.又叫狄克斯特拉算法.这是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中 ...
- dijkstra邻接表_掌握算法-图论-最短路径算法-Dijkstra算法
如果图是赋权图,那么问题就变得更困难了不过我们仍然可以使用来自无权情形时的想法. 我们保留所有与前面相同的信息.因此,每个顶点或者标记为Known的,或者标记为Unknown的.像之前一样,对每一个顶 ...
- 单源最短路径算法---Dijkstra
Dijkstra算法树解决有向图G=(V,E)上带权的单源最短路径问题,但是要求所有边的权值非负. 解题思路: V表示有向图的所有顶点集合,S表示那么一些顶点结合,从源点s到该集合中的顶点的最终最短路 ...
最新文章
- c语言编程 构建围墙,c语言程序设计朝盛 综合程序练习题.ppt
- 【设计干货】Facebook设计APP时的14个必考题
- 高等数理统计(part2)--常见的离散型分布
- 【软件开发底层知识修炼】二十五 ABI之函数调用约定二之函数返回值为结构体时的约定
- 今天pycharm不能正常使用了
- 计算机一级电子表格插入表格,计算机一级电子表格
- metrics的timer功能在java项目中的使用方法
- Emmet插件比较实用常用的写法
- 宅家36天咸鱼翻身入职腾讯,值得收藏!
- 辣条社区:问题解答、面试系列、求职助力、学习资源,你需要的都在这里
- Spring事务管理2----编程式事务管理
- OpenCV2中矩阵的归一化 normalize函数详解
- 破14亿,用Python分析我国存在哪些人口危机!
- 精美教师说课试讲教学通用PPT模板
- Echarts堆叠柱状图显示百分比
- [CF106C]Buns -多重背包
- 自学编程难吗?如何学?
- 高性价比降噪耳机推荐,2023年降噪耳机排行榜推荐
- python讲得比较好的老师_Python学习讲师哪个好?
- c++ math库函数
热门文章
- tomcat的备份脚本
- 忘记token怎么加入k8s集群
- 三十六、rsync通过服务同步、Linux系统日志、screen工具
- SUSE各个系统版本安装saltstack方法
- 战痕————道具系统介绍
- python3 32位_Python 3.6.8软件安装教程
- mes实施顾问前景如何_国匠智能制造培训|MES的两种实施顾问类型
- oracle输出查询返回多行,ORA-01427:单行子查询返回多行
- 2021年中宁中学高考成绩查询,2021宁夏中卫市重点高中排名
- 天涯明月刀开发_《天涯明月刀OL腾讯旗下 北极光工作室的 厄运魔咒:“做什么凉什么”》...