最短路径算法----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和A*
在设计基于地图的游戏,特别是isometric斜45度视角游戏时,几乎必须要用到最短路径算法.Dijkstra算法是寻找当前最优路径(距离原点最近),如果遇到更短的路径,则修改路径(边松弛). Ast ...
- 最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)(转)
一,问题描述 在英文单词表中,有一些单词非常相似,它们可以通过只变换一个字符而得到另一个单词.比如:hive-->five:wine-->line:line-->nine:nine- ...
- 有向有权图的最短路径算法--Dijkstra算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Di ...
- 带权图的最短路径算法(Dijkstra)实现
一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...
- 最短路径算法——Dijkstra,Bellman-Ford,Floyd-Warshall,Johnson
根据DSqiu的blog整理出来 :http://dsqiu.iteye.com/blog/1689163 PS:模板是自己写的,如有错误欢迎指出~ 本文内容框架: §1 Dijkstra算法 §2 ...
- 最短路径算法——Dijkstra算法
在路由选择算法中都要用到求最短路径算法.最出名的求最短路径算法有两个,即Bellman-Ford算法和Dijkstra算法.这两种算法的思路不同,但得出的结果是相同的. 下面只介绍Dijkstra算法 ...
- 最短路径算法——Dijkstra算法与Floyd算法
转自:https://www.cnblogs.com/smile233/p/8303673.html 最短路径 ①在非网图中,最短路径是指两顶点之间经历的边数最少的路径. AE:1 ADE:2 ...
- 最短路径算法-Dijkstra
Dijkstra是解决单源最短路径的一般方法,属于一种贪婪算法. 所谓单源最短路径是指在一个赋权有向图中,从某一点出发,到另一点的最短路径. 以python代码为例,实现Dijkstra算法 1.数据 ...
- 单源最短路径算法---Dijkstra
Dijkstra算法树解决有向图G=(V,E)上带权的单源最短路径问题,但是要求所有边的权值非负. 解题思路: V表示有向图的所有顶点集合,S表示那么一些顶点结合,从源点s到该集合中的顶点的最终最短路 ...
- 最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现(C/C++)
Dijkstra算法 ———————————最后更新时间:2011.9.25———————————Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径. ...
随机推荐
- 从MS Word到Windows Live Writer
在做笔记的时候,喜欢使用Word进行排版及插入图片,但是当将笔记发布的时候,一般的网站是不支持直接将Word中的图片进行上传的,此时使用Windows Live Writer是一个不错的选择. 可是, ...
- java中JDK环境变量的配置
JDK的配置在 window中的配置,我的电脑-->属性-->高级系统设置-->高级-->环境变量中配置,具体下图
- less(css)语言快速入门
转载 原文地址:https://www.ibm.com/developerworks/cn/web/1207_zhaoch_lesscss/ 简介 CSS(层叠样式表)是一门历史悠久的标记性语言,同 ...
- Java学习--基本数据类型的定义和运算2
例1 public class OperateDemo01{ public static void main(String args[]){ int num = 22 ; System.out.pri ...
- 笔记1:jmeter性能测试使用示例(原文:http://blog.csdn.net/zhongweijian/article/details/7619319)
jmeter是一个简单开源的纯java的性能测试工具.今天学习了jmeter使用了下jmeter,使用起来非常简单. 如果我们要对163的首页性能进行简单测试,我们可以按照以下步骤进行. 1.在测试计 ...
- unigui在阿里云服务器上部署
unigui在阿里云服务器上部署 客户租用了阿里云WINDOWS2008服务器,部署UNIGUI发现死活不行,WINDOWS2008自带的IE9浏览器打开URL,卡死在loading...... 我远 ...
- Delphi-idHttp-Post JSON用法 good
从国外网站抄来的代码 Delphi source: http := TIdHttp.Create(nil);http.HandleRedirects := True;//允许头转向http.ReadT ...
- 索引视图DEMO2
use tempdb ----在创建视图和所有底层表时,必须打开ANSI_NULLS以及QUOTED_IDENTIFIER选项 --SET ANSI_NULLS ON --GO --SET QUOTE ...
- Spring IOC 容器源码分析 - 创建原始 bean 对象
1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...
- AJPFX:外汇的爆仓和追加保证金
在外汇交易中,当可用保证金变成0时,账户即会爆仓.而为了防止爆仓,您可以在可用保证金不足时追加保证金以防止爆仓. 例如,您在AJPFX的账户是100倍的杠杆,一手欧美货币对合约为10万美金(1 LOT ...