dijkstra 最短路径算法

Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

  Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。

其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。

初始时,S中仅含有源。设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径长度。Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。

例如,对下图中的有向图,应用Dijkstra算法计算从源顶点1到其它顶点间最短路径的过程列在下表中。

Dijkstra算法的迭代过程:

参考书上的部分代码

void ShortestPath(Graph<T,E> &G , T v ,E dist[] ,int path[] )  {//G是所给图,T是顶点的数据类型,E是顶点边上权值的类型
	//path是用来存放求到最短路的路径

	int n = G.getNum() ;//先求出图中顶点的数目,数量为n
	bool *S = new bool[n] ;//开辟一个bool型的集合S
	int  i, j , k ;
	E w ;
	E min ;
	for(i = 0; i<n;i++) { //这个循环的作用是初始化集合S和path数组
		dist[i] =G.getWeight(v,i) ;//存放v和i之间的权值
		S[i] = false ; //点i未访问
		if (i != v && dist[i] <maxValue)
			path[i] = v ;//初始化
		else
			path[i] = -1 ;

	}

	S[v] =true ;//v加入顶点集合
	dist[v] = 0 ;
	for( i =0;i<n-1;i++) {
		min = maxValue ;
		int u = v ;
		for(j =0; j < n ;j++) {
			if(S[j] == false && dist[j] <min ) {   u = j ; min =dist[j] ;}
			S[u] =true ; //将顶点u 加入集合S
			for(k=0;k< n ;k++ ) {
				w= G.getWeight(u,k) ;
				if(S[k] == false && w<maxValue && dist[u] +w<dist[k] ) {
					dist[k] = dist[u] +w ;
					path[k] = u ;
				}
			}
		}
	}
}

因为是看着书学的所以思想和代码也基本和书上一样了,可以自己敲出来,书上这个算法写的不错,值得把玩,

maxValue指的是源点到顶点是没有边的,就把权值赋为maxValue。 判断结束的方法是直到所有的顶点都进入S集合了,就成功,相当于都true了~~

时间: 2024-11-23 03:07:22

dijkstra 最短路径算法的相关文章

Dijkstra最短路径算法[贪心]

Dijkstra算法的标记和结构与prim算法的用法十分相似.它们两者都会从余下顶点的优先队列中选择下一个顶点来构造一颗扩展树.但千万不要把它们混淆了.它们解决的是不同的问题,因此,所操作的优先级也是以不同的方式计算的:Dijkstra算法比较路径的长度,因此必须把边的权重相加,而prim算法则直接比较给定的权重. 源最短路径问题给定一个带权有向图 G=(V,E) ,其中每条边的权是一个非负实数.另外,还给定 V 中的一个顶点,称为源.现在我们要计算从源到所有其他各顶点的最短路径长度.这里的长度

Dijkstra最短路径算法

求下图中的1号顶点到2.3.4.5.6号顶点的最短路径. 与Floyd-Warshall算法一样这里仍然使用二维数组e来存储顶点之间边的关系,初始值如下. 我们还需要用一个一维数组dis来存储1号顶点到其余各个顶点的初始路程,如下. 我们将此时dis数组中的值称为最短路的“估计值”. 既然是求1号顶点到其余各个顶点的最短路程,那就先找一个离1号顶点最近的顶点.通过数组dis可知当前离1号顶点最近是2号顶点.当选择了2号顶点后,dis[2]的值就已经从“估计值”变为了“确定值”,即1号顶点到2号顶

【算法日记】Dijkstra最短路径算法

上一篇再说广度优先搜索的适合提到了图. 狄克斯拉特算法是在图的基础上增加了 加权图的概念.就是节点和节点之间是有不同距离的 1.算法实例 用Dijkstra算法找出以A为起点的单源最短路径步骤如下 算法实现 # Dijkstra算法--通过边实现松弛 # 指定一个点到其他各顶点的路径--单源最短路径 # 初始化图参数 G = {1:{1:0, 2:1, 3:12}, 2:{2:0, 3:9, 4:3}, 3:{3:0, 5:5}, 4:{3:4, 4:0, 5:13, 6:15}, 5:{5:0

Dijkstra 最短路径算法 秒懂详解

想必大家一定会Floyd了吧,Floyd只要暴力的三个for就可以出来,代码好背,也好理解,但缺点就是时间复杂度高是O(n³). 于是今天就给大家带来一种时间复杂度是O(n²),的算法:Dijkstra(迪杰斯特拉). 这个算法所求的是单源最短路,好比说你写好了Dijkstra的函数,那么只要输入点a的编号,就可算出图上每个点到这个点的距离. 我先上一组数据(这是无向图): 5 6 1 2 5 1 3 8 2 3 1 2 4 3 4 5 7 2 5 2 图大概是这个样子: 我们以1为源点,来求所

Dijkstra最短路径算法(C#实现)

学习了最短路劲算法,就想用C#语言实现一下,算自己的总结提高,也为初学者提供帮助闲话不说,首先陈述一下dijkstra算法的思想 1.设置一个集合S,用来存放确定了最短路径的顶点,一个集合U,用来存放没有确定最短路径的顶点,一个集合distance,表示起点到该点在此刻的最短距离, 集合pre,表示该点取到当前路径时的上一个参考点,初始参考点下标都为0:集合Isfor表示是否确定已经为最短路径了. 2.先把起点V0的下标0加到集合S,然后标记Isfor[0]=true;把起点的下标标记为把V1,

Dijkstra 最短路径算法详解 无向图

对于最短路径问题,这里介绍一种O(N^2)的求解方法. 对于求最短路径的问题一般都会给出一幅图,或者边与边的关系.如上图. 假设我们起点是A,我们要求到F的最短距离,我们会怎么做? 首先,因为A是起点,所以我们把对于每个点都有个参数,相对于A的距离,默认除了A到A为0,其他都是无穷大. 从起点A开始,我们更新与A相连通的点到A的距离,并把A点标记.如图: 我们遍历一次所有点与A的距离,找到最小的,这里是点B. 以它为起点,把它周围未被标记的点拿来做比较,显然,像F这种没有与A练过的点,当前距离就

17.boost dijkstra最短路径算法

到某个点的最短距离                到终点的最短路径 完整代码 1 #include <iostream> 2 #include <string> 3 #include <utility> 4 #include <vector> 5 #include <deque> 6 #include <boost/graph/adjacency_list.hpp> 7 //A*寻路算法 8 #include <boost\gr

【转】Fibonacci 斐波纳契堆优化 Dijkstra 最短路径算法

话不多说,拿来主义,直接上代码! PS:打印最短路径我还不晓得怎么加,如有哪位大神知道,还请mark一下! 1 /*********************************************************************** 2 * File: FibonacciHeap.java 3 * Author: Keith Schwarz ([email protected]) 4 * 5 * An implementation of a priority queue

最短路径算法学习总结

Dijkstra最短路径算法: dijkstra 算法的优点在于可以求出从一点到所有其他点的最短距离: input: 5 71 2 101 3 201 5 302 5 102 3 54 5 204 3 30 output: 0 10 15 40 20//这是求的在这颗树中,1到所有点的最短距离 1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int N=1100; 5 const int