Fancy DSA Fancy DSA
数据结构
算法
LeetCode
  • 关于
  • 导航 (opens new window)
  • 分类
  • 标签
  • 归档
设计模式 (opens new window)
博客 (opens new window)
GitHub (opens new window)

Jonsam NG

想的更多,也要想的更远
数据结构
算法
LeetCode
  • 关于
  • 导航 (opens new window)
  • 分类
  • 标签
  • 归档
设计模式 (opens new window)
博客 (opens new window)
GitHub (opens new window)
  • 开始上手
  • Plan 计划
  • Roadmap 路线
  • 算法简介
  • Sort 排序

  • Search 搜索

  • Recursive 递归

  • Graph 图

    • BellmanFord [贝尔曼-福特算法]
    • BreadthFirstSearch [广度优先搜索/BFS]
    • BreadthFirstShortestPath [广度优先寻最短路径]
    • ConnectedComponents [连通元件]
    • Density [图的密度]
    • DepthFirstSearch [深度优先搜索]
    • Dijkstra [迪杰斯特拉算法]
    • FloydWarshall [弗洛伊德算法]
      • 介绍
      • 原理
      • 算法描述
      • 演示
      • 实现
      • 参考
    • KruskalMST [克鲁斯克尔算法]
    • NodeNeighbors [节点邻域]
    • NumberOfIslands [岛屿数量]
    • PrimMST [普林姆算法]
  • Tree 树

  • Math 数学

  • Hash 哈希

  • String 字符串

  • BitManipulation 位操纵

  • Backtracking 回溯

  • DynamicProgramming 动态规划

  • Cache 缓存

  • Array 数组

  • Ciphers 密码学

  • Conversions 转换

  • ProjectEuler 欧拉计划

  • 其他

  • 算法
  • Graph 图
jonsam
2022-05-01
目录

FloydWarshall [弗洛伊德算法]

# 介绍

Floyd-Warshall 算法(英语:Floyd-Warshall algorithm),中文亦称弗洛伊德算法或佛洛依德算法,是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包。

Floyd-Warshall 算法的时间复杂度为O(N3)O(N^{3})O(N3),空间复杂度为O(N2)O(N^{2})O(N2)。

# 原理

Floyd-Warshall 算法的原理是动态规划。设 Di,j,kD_{i, j, k}Di,j,k​ 为从 iii 到 jjj 的只以 (1..k)(1 . . k)(1..k) 集合中的节点为中间节点的最短路径的长度。

  • 若最短路径经过点 k\mathrm{k}k, 则 Di,j,k=Di,k,k−1+Dk,j,k−1D_{i, j, k}=D_{i, k, k-1}+D_{k, j, k-1}Di,j,k​=Di,k,k−1​+Dk,j,k−1​;
  • 若最短路径不经过点 k, 则 Di,j,k=Di,j,k−1D_{i, j, k}=D_{i, j, k-1}Di,j,k​=Di,j,k−1​ 。

因此,Di,j,k=min⁡(Di,j,k−1,Di,k,k−1+Dk,j,k−1)D_{i, j, k}=\min \left(D_{i, j, k-1}, D_{i, k, k-1}+D_{k, j, k-1}\right)Di,j,k​=min(Di,j,k−1​,Di,k,k−1​+Dk,j,k−1​) 。在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维。

动态规划

动态规划(英语:Dynamic programming,简称 DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。

# 算法描述

Floyd-Warshall 算法的伪代码描述如下:

// let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity)
for each vertex v
   dist[v][v] ← 0
for each edge (u,v)
   dist[u][v] ← w(u,v)  // the weight of the edge (u,v)
for k from 1 to |V|
   for i from 1 to |V|
      for j from 1 to |V|
         if dist[i][j] > dist[i][k] + dist[k][j] 
             dist[i][j] ← dist[i][k] + dist[k][j]
         end if
1
2
3
4
5
6
7
8
9
10
11

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

# 演示

# 实现

# JavaScript

/*
  Source:
    https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm

  Complexity:
    O(|V|^3) where V is the set of vertices
*/

const FloydWarshall = (dist) => {
  // Input:- dist: 2D Array where dist[i][j] = edge weight b/w i and j
  // Output:- dist: 2D Array where dist[i][j] = shortest dist b/w i and j
  const n = dist.length
  for (let k = 0; k < n; k++) {
    for (let i = 0; i < n; i++) {
      for (let j = 0; j < n; j++) {
        if (dist[i][j] > dist[i][k] + dist[k][j]) {
          // dist from i to j via k is lesser than the current distance
          dist[i][j] = dist[i][k] + dist[k][j]
        }
      }
    }
  }
  return dist
}

// For the following graph (edge weights are shown in brackets)
//  4       1       dist[1][2] = dist[2][1] = 1
//   \  (2)/ \      dist[1][3] = dist[3][1] = 2
//    \   /   \(1)  dist[1][4] = dist[4][1] = Infinity
//  (1)\ /     \    dist[3][4] = dist[4][3] = 1
//      3       2   dist[2][4] = dist[4][2] = Infinity
//                  dist[2][3] = dist[3][2] = Infinity
// Output should be:
// [ [0, 1, 2, 3],
//   [1, 0, 3, 4],
//   [2, 3, 0, 1],
//   [3, 4, 1, 0] ]

// FloydWarshall(
//     [[0, 1, 2, Infinity],
//       [1, 0, Infinity, Infinity],
//       [2, Infinity, 0, 1],
//       [Infinity, Infinity, 1, 0]
//     ]
//   )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

注意:

  • 不需要 startNode。

# 参考

  • Floyd–Warshall algorithm - Wikiwand (opens new window)
  • Floyd-Warshall 算法 - Wikiwand (opens new window)
编辑 (opens new window)
上次更新: 2022/10/18, 19:00:15
Dijkstra [迪杰斯特拉算法]
KruskalMST [克鲁斯克尔算法]

← Dijkstra [迪杰斯特拉算法] KruskalMST [克鲁斯克尔算法]→

最近更新
01
0-20题解
10-31
02
本章导读
10-31
03
算法与转换:Part1
10-28
更多文章>
Theme by Vdoing | Copyright © 2022-2022 Fancy DSA | Made by Jonsam by ❤
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式