python贪心算法最短路径_贪心算法2-单源最短路径

1.问题分析

给定有向带权图G = (V, E),其中每条边的权是非负实数。此外,给定V中的一个顶点u,称为源点。现在要计算从源到所有其它各顶点的最短路径,这里的路径指的是路径上各边的权值之和。

求单源最短路径的算法是Dijkstra,荷兰人,计算机科学家,在1972年获得图灵奖。

2.算法设计

Dijkstra是解决单源最短路径的贪心算法。算法的基本思想首先假定源点为u,顶点集合V被划分为两部分:集合S和集合V-S。初始时S中仅含有源点u,源点u到集合V-S中包含的顶点的最短路径待定。我们把从源点出发只经过S中的点到达V-S中的点的路径称为特殊路径,并用数组dist[]记录当前源点到每个点所对应的特殊路径的长度。

Diskstra算法采用的贪心策略是选择特殊路径长度最短的路径,将其连接的V-S中的顶点加入到集合S中,同时更新数组dist[]。一旦S中包含了所欲顶点,dist[]就是从源点到其它顶点之间的最短路径长度。

算法需要维护的数据结构有三个( 理解数据结构的意义是重点!):

邻接矩阵graph[][]:用来保存相邻顶点边上的权值,如果两个顶点之间没有边相连,则它们之间的权值为无穷大;

最短距离数组dist[i]:用来记录点i的最短路径长度;

前驱数组pre[i]:用来记录最短路径上顶点i的前驱;

选中顶点数组isIn[i]:bool类型,用来表示顶点i当前是否被选中。

算法执行流程

初始化。令集合S = {u},初始化graph[][],对于集合V-S中的所有顶点i,初始化dist[i] = map[u][i], 如果源点到顶点i之间有边相连,初始化pre[i] = u,否则pre[i] = -1。同时令isIn[u] = true,表示选中,其它顶点都设为false;(1)

找最小。在集合V-S中找出离源点最近的,就是在dist[]中找到值最小的顶点m,但前提是isIn[m]=false;(2)

将选中的顶点j加入到集合S中,同时更新V-S,这一步操作实际就是令isIn[m] = true;(3)

更新路径。选中顶点j后,需要判断和j相连的其它顶点k通过走顶点j是否可以缩短到源点到距离,即是否有“捷径”可走。如果dist[k] > dist[m] + graphm,说明有“捷径”可走,则更新dist[k] = dist[m] + graphm,同时更新顶点k的前驱,零pre[k] = m;(4)

判断S-V集合中是否为空,如果为空,算法结束,否则转到流程(3)继续选择;(5)

由此,可求得从源点u到图G的其余各个顶点的最短路径及长度,并且可以通过数组pre[]回溯找到最短路径上依次经过的顶点。

算法图解

(1) 原始数据结构

(2) 初始化最短距离数组dist[][]和前驱数组pre[]

(3) 找dist[]值最小的顶点并加入集合S

(4) 更新路径

(5) 继续找dist[]值最小的顶点并加入集合S

(6) 更新路径

(7) 继续找dist[]值最小的顶点并加入集合S

(8) 更新路径(此次没有数据需要更新!)

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值