Dijkstra算法 Graph: min-path

Definition

对于无权图来说,我们可以用广度优先搜索方法(BFS, Breadth-First-Search)查找最短路径,但是当图是带权图时,带权路径长度为:从一个顶点到其余任意一个顶点的一条路径所经过的边上的权值之和,带权路径最短的即为最短路径

Dijkstra 算法

Definition

求某个源点到其他各顶点的最短路径, S S S 集合记录已经求得最短路径的顶点,通过一个数组 s[] 来实现,初始化值为 0 0 0,放入集合置为 1 1 1,此外还需要两个数组:

  • dist[]:记录当前从源点 v 0 v_{0} v0 到其他各顶点的路径长度,假如边的权重用一个二维数组来存储的话,例如 arcs[][],如果两点之间没有路径则为 ∞ \infin ,这样我们初始化 dist[i]=arcs[0][i]
  • path[]:表示从源点到某个顶点最短路径的前驱顶点(即终点的前一个顶点,然后我们再找到这个顶点的前一个顶点,这样回溯可以得到从源点到达每一个顶点的最短路径)

算法步骤其实很简单,有点类似Prim算法,就是每次从剩下的顶点集中选择dist[i]最小的顶点添加到 S S S 中,然后对加入新顶点之后的dist[]进行修改,重复这个过程直到所有的顶点都被加入到 S S S 中,这样我们就得到了从源点到每个顶点之间的最短路径了

Performance

这个算法同样是采取贪心算法的思想,采用邻接矩阵和带权的邻接表法时间复杂度都是 O ( ∣ V ∣ 2 ) O(|V|^{2}) O(V2)

Problem

算法的局限性:

  • 如果图包含负边,算法不适用
  • 到特定顶点的最短距离求解方法复杂

Floyd算法

如果你熟悉 W a r s h a l l Warshall Warshall 算法的话,那相信这个算法对你来说是简单易懂的,因为实际上都是考虑中间点—— k k k,即不断尝试往一个顶点和另外一个顶点之间添加一个新的中间点,观察是否会得到更优的路径长度,然后不断更新这个路径长度,直到我们考虑了所有的中间点,最终我们就得到了我们的最短路径和最短路径长度了,复杂度为 O ( ∣ V ∣ 3 ) O(|V|^{3}) O(V3)

这个算法允许负边存在,但不允许负环;此外这个算法同样适用于带权无向图(可以把无向边看成往返边)

Implementation

void floydMinPath(Graph G){
	int n = G.vexNum;
	// suppose that the very graph is stored by adjacency matrix with element A[i][j]
	// stores length of path from vi to vj
	int** A = G.E;
	// after k pass could we obtain 
	for(int k = 0; k < vexNum; k++){
		for(int i = 0; i < vexNum; i++){
			for(int j = 0; j < vexNum; j++){
				int temp = A[i][k] + A[k][j];
				A[i][j] = A[i][j] > temp?A[i][j]:temp;
			}
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值