《算法分析与设计》第四章 单源最短路径-2
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法分析与设计
1
学习内容与目标
贝尔曼(Bellman-Ford) a) b)
简介 基本思想(重点)
c)
d) e)
代码实现(难点)
复杂度分析
队列优化(重点)
单源最短路径算法——应用
单源最短路径—给定带权有向图G=(V, E)和源点 v∈V,求从v到G中其余各顶点的最短路径。 计算机网络传输—怎样找到一种最经济的方式,从 一台计算机向网上所有其它计算机发送一条消息。 交通—旅客从A城到B城选择一条中转次数/费用最少 的路线 导航—考虑请求量的问题,在基础算法之上进行改 进
1.初始化:从v出发到其余各顶点vi的最短路径长度 D[i]初值为:源点D[v]=0,其余顶点D[vi]=+∞。 2.迭代松弛:反复对边集E中的每条边进行松弛操作 ,使得顶点集V中的每个顶点v的最短距离估计值逐 步逼近其最短距离(收敛);(松弛|v|-1次)
贝尔曼-福特(Bellman-Ford)-基本思想
4.对队首的顶点重复执行如上的操作,直至队列为空。
注意:如果某个点进入队列的次数超过n次,那么这个 图则肯定存在负权环。
示例
-3
B
2
A A
5
C
3
E
2
D
Bellman-Ford的队列优化-伪代码
1.
2. 3. 4. 5. 6. 7.
ProcedureSPFA;
Begin initialize-single-source(G,s); initialize-queue(Q); enqueue(Q,s); //源点入队 while not empty(Q) do begin u:=queue(head); //获取队首元素
for each edge(u,v) ∈E(G) do dist[v]=dist[u]+w(u,v) for each edge(u,v) ∈E(G) do return false return true
If dist[v]> dist[u]+ w(u,v) then //松弛判断
9.
10. 11.
3.检验负权回路:判断边集E中的每一条边的两个 端点是否收敛。如果存在未收敛的顶点,则算法返 回false,表明问题无解;否则算法返回true,并 且从源点可达的顶点v的最短距离保存在 d[v]中。
示例
-3
B
2
A A
5
C
3
E
2
D
边的顺序不同,求解的过程不同;但是松弛判 断的比较需要:(V-1)E=20次。
启发我们:每次仅对最短路估计值发生变化的顶
点的所有出边进行松弛,因此有了Bellman-Ford 的队列优化。
Bellman-Ford的队列优化
1.每次选取队首顶点u,对顶点u的所有出边进行松弛操 作; 2.如果松弛成功,且v(存在u->v)不在当前队列中, 将v入队列; 3.对顶点u的所有出边松弛完后,u出队。
If dist[v]> dist[u]+ w(u,v) then
//若存在,问题无解,返回False //若不存在,返回True,存在从源点s到各个点的最短路径
算法时间复杂度
有向图G的顶点数为V,边数为E;
1.初始化INITIALIZE-SINGLE-SOURCE(G,S)所需时间为 O(V);
8.
9. 10. 11. 12. 13. 14.
for each v∈adj[u] do begin
tmp:=d[v]; relax(u,v); dequeue(Q); end; End; //松弛 if(tmp<>d[v])and(not v in Q)then enqueue(Q,v);
练习1
贝尔曼-福特(Bellman-Ford)-简介
Lester
Ford在1956年和美国应用数学家理查 德.贝尔曼于1958 年都发表该算法。 可解决带负权边的有向图中最短路径问题, 但要求有向图无负权回路。
是从一个顶点到其余各顶点的最短路径算法,
贝尔曼-福特(Bellman-Ford)-简介
Bellman
- ford算法是求含负权图的单源最短 路径算法,算法比较简单,核心代码只有4行 但效率较低。 其原理为持续地进行松弛,在每次松弛时把 每条边d(源点到其余各顶点的最短路径)值更新一下, 若在n-1次松弛后还能更新,则说明图中有负 环,因此无法得出结果,否则就完成。
贝尔曼-福特(Bellman-Ford)-基本思想
2.迭代松弛共执行V-1次,每趟操作的运行时间为O(E);
3.检验负权回路的运行时间为O(E);
因此该算法的执行时间为O(VE)。
Bellman-Ford的队列优化(SPFA)
Bellman-Ford算法在每实施一次松弛操作后,就
会有一些顶点已经求得其最短路,之后这些顶点 的最短路的估计值不会受后续松弛操作的影响, 但是算法中每次还要判断是否需要松弛,无疑浪 费了时间。
使用SPFA算法求解A到其余顶点的单源最短路径
2
2
7
3
1 A
10
3
6 4
5
5
Leabharlann Baidu
4
练习2
用C/C++/Java等编程语言实现SPFA算法
Bellman-Ford 伪代码
1. 2. 3. 4. 5. 6. 7. 8.
for each vertex v ∈ V(G) do dist[v] ←+∞ dist[s] ←0; for i=1 to |v|-1 do
// 初始化 //初始化结束 //2阶段 开始,外循环进行 //对每条边进行松弛 //2阶段结束 松弛操作 //3判断是否存在从源点s可达的负权值回路
1
学习内容与目标
贝尔曼(Bellman-Ford) a) b)
简介 基本思想(重点)
c)
d) e)
代码实现(难点)
复杂度分析
队列优化(重点)
单源最短路径算法——应用
单源最短路径—给定带权有向图G=(V, E)和源点 v∈V,求从v到G中其余各顶点的最短路径。 计算机网络传输—怎样找到一种最经济的方式,从 一台计算机向网上所有其它计算机发送一条消息。 交通—旅客从A城到B城选择一条中转次数/费用最少 的路线 导航—考虑请求量的问题,在基础算法之上进行改 进
1.初始化:从v出发到其余各顶点vi的最短路径长度 D[i]初值为:源点D[v]=0,其余顶点D[vi]=+∞。 2.迭代松弛:反复对边集E中的每条边进行松弛操作 ,使得顶点集V中的每个顶点v的最短距离估计值逐 步逼近其最短距离(收敛);(松弛|v|-1次)
贝尔曼-福特(Bellman-Ford)-基本思想
4.对队首的顶点重复执行如上的操作,直至队列为空。
注意:如果某个点进入队列的次数超过n次,那么这个 图则肯定存在负权环。
示例
-3
B
2
A A
5
C
3
E
2
D
Bellman-Ford的队列优化-伪代码
1.
2. 3. 4. 5. 6. 7.
ProcedureSPFA;
Begin initialize-single-source(G,s); initialize-queue(Q); enqueue(Q,s); //源点入队 while not empty(Q) do begin u:=queue(head); //获取队首元素
for each edge(u,v) ∈E(G) do dist[v]=dist[u]+w(u,v) for each edge(u,v) ∈E(G) do return false return true
If dist[v]> dist[u]+ w(u,v) then //松弛判断
9.
10. 11.
3.检验负权回路:判断边集E中的每一条边的两个 端点是否收敛。如果存在未收敛的顶点,则算法返 回false,表明问题无解;否则算法返回true,并 且从源点可达的顶点v的最短距离保存在 d[v]中。
示例
-3
B
2
A A
5
C
3
E
2
D
边的顺序不同,求解的过程不同;但是松弛判 断的比较需要:(V-1)E=20次。
启发我们:每次仅对最短路估计值发生变化的顶
点的所有出边进行松弛,因此有了Bellman-Ford 的队列优化。
Bellman-Ford的队列优化
1.每次选取队首顶点u,对顶点u的所有出边进行松弛操 作; 2.如果松弛成功,且v(存在u->v)不在当前队列中, 将v入队列; 3.对顶点u的所有出边松弛完后,u出队。
If dist[v]> dist[u]+ w(u,v) then
//若存在,问题无解,返回False //若不存在,返回True,存在从源点s到各个点的最短路径
算法时间复杂度
有向图G的顶点数为V,边数为E;
1.初始化INITIALIZE-SINGLE-SOURCE(G,S)所需时间为 O(V);
8.
9. 10. 11. 12. 13. 14.
for each v∈adj[u] do begin
tmp:=d[v]; relax(u,v); dequeue(Q); end; End; //松弛 if(tmp<>d[v])and(not v in Q)then enqueue(Q,v);
练习1
贝尔曼-福特(Bellman-Ford)-简介
Lester
Ford在1956年和美国应用数学家理查 德.贝尔曼于1958 年都发表该算法。 可解决带负权边的有向图中最短路径问题, 但要求有向图无负权回路。
是从一个顶点到其余各顶点的最短路径算法,
贝尔曼-福特(Bellman-Ford)-简介
Bellman
- ford算法是求含负权图的单源最短 路径算法,算法比较简单,核心代码只有4行 但效率较低。 其原理为持续地进行松弛,在每次松弛时把 每条边d(源点到其余各顶点的最短路径)值更新一下, 若在n-1次松弛后还能更新,则说明图中有负 环,因此无法得出结果,否则就完成。
贝尔曼-福特(Bellman-Ford)-基本思想
2.迭代松弛共执行V-1次,每趟操作的运行时间为O(E);
3.检验负权回路的运行时间为O(E);
因此该算法的执行时间为O(VE)。
Bellman-Ford的队列优化(SPFA)
Bellman-Ford算法在每实施一次松弛操作后,就
会有一些顶点已经求得其最短路,之后这些顶点 的最短路的估计值不会受后续松弛操作的影响, 但是算法中每次还要判断是否需要松弛,无疑浪 费了时间。
使用SPFA算法求解A到其余顶点的单源最短路径
2
2
7
3
1 A
10
3
6 4
5
5
Leabharlann Baidu
4
练习2
用C/C++/Java等编程语言实现SPFA算法
Bellman-Ford 伪代码
1. 2. 3. 4. 5. 6. 7. 8.
for each vertex v ∈ V(G) do dist[v] ←+∞ dist[s] ←0; for i=1 to |v|-1 do
// 初始化 //初始化结束 //2阶段 开始,外循环进行 //对每条边进行松弛 //2阶段结束 松弛操作 //3判断是否存在从源点s可达的负权值回路