Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包。

Floyd-Warshall算法的时间复杂度空间复杂度

原理

Floyd-Warshall算法的原理是动态规划

为从的只以集合中的节点为中间节点的最短路径的长度。

  1. 若最短路径经过点k,则
  2. 若最短路径不经过点k,则

因此,

在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维。(见下面的算法描述)

算法描述

Floyd-Warshall算法的描述如下:

for k ←  to n do
for i ← to n do
for j ← to n do
if (D_{i,k} + D_{k,j} < D_{i,j}) then
D_{i,j} ← D_{i,k} + D_{k,j};

其中表示由点到点的代价,当为 ∞ 表示两点之间没有任何连接。

Floyd-warshall 算法总结

1. 初始化时, 将 dp[i][i] 设置为 0

2. i, j 均从 1 开始遍历

3. 从状态转移方程到代码的实现, 最关键的一步是确定最外层的循环变量是谁, 而最外层的循环变量又是从状态转移方程本身推出. 比如在 Floyd 算法中, 状态转移方程是

当 k 在最短路径上时, dp(i, j, k) = dp(i, k, k-1) + dp(k, j, k-1)

当 k 不在最短路径时, dp(i, j, k) = dp(i, j, k-1)

可以转化为 g(k) = f(k, k-1), 因此应该把 k 作为最外层的循环变量

4. 空间压缩. 在求解 dp(i, j, k) 时, 会用到 dp(i, k, k-1) 和 dp(k, j, k-1) 以及 dp(i, j, k-1). 新生成的数据 dp(i, j, k) j != k 不会被重复利用, 因此可以使用二维空间

Bellmanford 算法

1. 与 Dijsktra 算法的比较. D 是一种贪心算法, 贪心策略为选取未被处理的最短的节点, 理由是该节点有潜力更新某些节点的距离, 使之变得更小, 每次对该节点的出边进行松弛. 而 B 算法简单的对所有的边进行松弛, 可以看出, D 算法进行的运算是 B 算法的子集.  B 算法的优点是不仅可以处理负权边, 还能判断图是否存在负环.

2. 松弛. 松弛实际上是对相邻节点的访问, 第 n 次松弛保证了保证了所有深度为 n 个节点得出了最短路径. 由于图最短路径最深至多是 V-1, 因此 V-1 次松弛即可确定所有点的最短路径

3. 负权环判定. 因为负权环可以无限制的拉低最短路径, 因此在进行第 V 次松弛后, 最短路径值有所减小, 那么可以肯定, 存在负权环

4. 朴素 BellmanFord 算法

procedure BellmanFord(list vertices, list edges, vertex source)
// 该实现读入边和节点的列表,并向两个数组(distance和predecessor)中写入最短路径信息 // 步骤1:初始化图
for each vertex v in vertices:
if v is source then distance[v] :=
else distance[v] := infinity
predecessor[v] := null // 步骤2:重复对每一条边进行松弛操作
for i from to size(vertices)-:
for each edge (u, v) with weight w in edges:
if distance[u] + w < distance[v]:
distance[v] := distance[u] + w
predecessor[v] := u // 步骤3:检查负权环
for each edge (u, v) with weight w in edges:
if distance[u] + w < distance[v]:
error "图包含了负权环"

5. SPFA 优化

SPFA 是 Shorest Path Faster Algorithm 的简写. SPFA 基于一个事实: 松弛有效的操作必然发生在松弛的前导节点成功松弛的节点上.

用一个队列记录松弛过的节点, 可以减少冗余计算, 将复杂度降低到 o(kE)

Begin
initialize-single-source(G,s);
initialize-queue(Q);
enqueue(Q,s);
while not empty(Q) do
begin
u:=dequeue(Q);
for each v∈adj[u] do
begin
tmp:=d[v];
relax(u,v);
if (tmp<>d[v]) and (not v in Q) then
enqueue(Q,v);
end;
end;
End;

Floyd 和 bellman 算法的更多相关文章

  1. 数据结构与算法--最短路径之Bellman算法、SPFA算法

    数据结构与算法--最短路径之Bellman算法.SPFA算法 除了Floyd算法,另外一个使用广泛且可以处理负权边的是Bellman-Ford算法. Bellman-Ford算法 假设某个图有V个顶点 ...

  2. SGU 455 Sequence analysis(Cycle detection,floyd判圈算法)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=455 Due to the slow 'mod' and 'div' operati ...

  3. 最短路径问题——bellman算法

    关于最短路径问题,最近学了四种方法——bellman算法.邻接表法.dijkstra算法和floyd-warshall算法. 这当中最简单的为bellman算法,通过定义一个边的结构体,存储边的起点. ...

  4. Bellman算法

    Bellman算法 当图有负圈的时候可以用这个判断最短路! [时间复杂度]O(\(nm\)) &代码: #include <bits/stdc++.h> using namespa ...

  5. Floyd最短路算法

    Floyd最短路算法 ----转自啊哈磊[坐在马桶上看算法]算法6:只有五行的Floyd最短路算法 暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计 ...

  6. UVA 11549 CALCULATOR CONUNDRUM(Floyd判圈算法)

    CALCULATOR CONUNDRUM   Alice got a hold of an old calculator that can display n digits. She was bore ...

  7. UVA 11549 Calculator Conundrum (Floyd判圈算法)

    题意:有个老式计算器,每次只能记住一个数字的前n位.现在输入一个整数k,然后反复平方,一直做下去,能得到的最大数是多少.例如,n=1,k=6,那么一次显示:6,3,9,1... 思路:这个题一定会出现 ...

  8. leetcode202(Floyd判圈算法(龟兔赛跑算法))

    Write an algorithm to determine if a number is "happy". 写出一个算法确定一个数是不是快乐数. A happy number ...

  9. 【啊哈!算法】算法6:只有五行的Floyd最短路算法

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

随机推荐

  1. Java:集合与数组转换

    List,Set转换为数组的方法. toArray函数有两种形式,一种无参数,一种带参数,注意带参数形式中,要指明数组的大小. public void convertCollectionToArray ...

  2. SQLite 日期 & 时间

    具体看http://www.runoob.com/sqlite/sqlite-date-time.html 不过实例介绍的不够详细,以下详细举例: SQLite包含了如下时间/日期函数:datetim ...

  3. Sublime Text 3 For Mac

    安装 Sublime Text 3 下载地址:http://www.sublimetext.com/3 我此时使用的是Build 3083版本. 安装 Package Control 这个是精华所在, ...

  4. thinkphp5的Redis缓存配置

    thinkphp采用cache类提供缓存功能支持,采用驱动方式,在使用缓存之前需要进行初始化操作.支持的缓存类型包括file.memcache.wincache.sqlite.redis和xcache ...

  5. 关于Unity中如何立即中断动画然后重新开始播放

    今天做一个FPS游戏的时候,用的是新版的动画系统,遇到一个问题. 就是用枪打敌人的时候,敌人会播放一个被击中的动画,但是如果在动画播放的过程中再射击敌人,敌人会先把第一个被击中的动画播放完,才再播放第 ...

  6. android读取大图片并缓存

    最近开发电视版的云存储应用,要求”我的相册“模块有全屏预览图片的功能,全屏分辨率是1920*1080超清.UI组件方面采用Gallery+ImageSwitcher组合,这里略过,详情参见google ...

  7. 【1】JVM-内存模型

    本篇其实就是一个读书笔记,书是<深入理解JAVA虚拟机>,在网上搜索JAVA内存,说的比较好的其实很多都源自这本书,作为一个JAVA程序员,理解虚拟机是通向高级程序员的必经道路.本篇中的图 ...

  8. python公司内部语言规范与语言风格

    一.python语言规范 1.1导入 Tip: 仅对包和模块使用导入 定义: 模块间共享代码的重用机制. 优点: 命名空间管理约定十分简单.每个标识符的源都用一种一致的方式指示.x.obj 表示obj ...

  9. SAP 金税接口代码 供参考

    程序可以通过抓取 客户 开票信息等 下载文本 导出 需要事先创建好几个structure zc0000sdt0016, zc0000sdt0017 REPORT zc0000sdr0016 NO ST ...

  10. Android Studio 出现 Build gradle project info

    导入Android Studio,一直停留在Build gradle project info.主要是因为google被墙,下载gradle很慢,有时候设置下载不成功. 参考链接 http://blo ...