【算法导论笔记】所有结点对的最短路径问题

基于矩阵乘法的动态规划算法求解所有最短路径

EXTEND_SHORTEST_PATHS(L, W)
  n = L.rows
  let L' = l'(i,j) be a new n*n matrix
  for i=1 to n
      for j=1 to n
          l'(i,j) = ∞
  return L'

SLOW-ALL-PATHS-SHORTEST-PATHS(W)
  n = W.rows
  L[1] = W
  for m=2 to n-1
      let L[m] be a new n*n matrix
      L[m] = EXTEND_SHORTEST_PATHS(L(m-1), W)
  return L[n-1]

使用重复平方技术来计算上述矩阵序列

FASTER-ALL-PAIRS-SHORTEST-PATHS(W)
  n = W.rows
  L[1] = W
  m = 1
  while m<n-1
      let L[2m] be a new n*n matrix
      L[2m] = EXTEND_SHORTEST_PATHS(L[m], L[m])
      m = 2m
  return L[m]

Floyd-Warshall算法(佛洛依德算法)

FLOYD-WARSHALL(W)
  n = W.rows
  D[0] = W
  for k=1 to n
      let D[k] = d[k](i,j) be a new n*n matrix
   for i=1 to n
      for j=1 to n
          d[k](i,j) = min(d[k-1](i,j), d[k-1](i,k)+d[k-1](k,j))
  return D[n]

有向图的传递闭包算法

TRANSITIVE-CLOSURE(G)
  n = G.V
  let T[0] = {t[0](i,j)} be a new n*n matrix
  for i=1 to n
      for j=1 to n
          if i==j or (i,j)∈G.E
              t[0](i,j) = 1
          else  t[0](i,j) = 0
  for k=1 to n
      let T[k] = {t[k](i,j)} be a new n*n matrix
      for i=1 to n
          for j=1 to n
              t[k](i,j) = t[k-1](i,j) ∨ (t[k-1](i,k)∧t[k-1](k,j))
  return T[n]

用于稀疏图的Johnson算法

JOHNSON(G, w)
  compute G', where G'.V = G.V∪{s},
      G'.E = G.V∪{(s,v):v∈G.V}, and
      w(s,v)=0 for all v∈G.V
  if BELLMAN-FORD(G', w, s) == FALSE
      print"the input graph contain a negative-weigh cycle"
  else  for each vertex v∈G'.V
          set h(v) to the value if δ(s,v)
              computed by the Bellman-Ford algorithm
        for each edge(u,v)∈G'.E
            w'(u,v) = w(u,v) + h(u) + h(v)
        let D={d(u,v)} be a new n*n matrix
        for each vertex u∈G'.V
            run DIJKSTRA(G,w',u) to compute δ'(u,v) for all δ∈G.V
            for each vertex v∈G.V
                d(u,v) = δ'(u,v) + h(v) - h(u)
  return D


Floyd算法是一种用于求解任意两结点最短路径的动态规划算法。下面是使用C++实现Floyd算法求解最短路径问题代码示例: ```cpp #include <iostream> #include <vector> #define INF 99999 // 使用Floyd算法求解任意两结点的最短路径 void floydWarshall(std::vector<std::vector<int>>& graph, int n) { std::vector<std::vector<int>> dist(n, std::vector<int>(n)); // 初始化距离矩阵 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { dist[i][j] = graph[i][j]; } } // 更新距离矩阵 for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (dist[i][k] + dist[k][j] < dist[i][j]) { dist[i][j] = dist[i][k] + dist[k][j]; } } } } // 打印最短路径 std::cout << "最短路径矩阵:" << std::endl; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (dist[i][j] == INF) { std::cout << "INF "; } else { std::cout << dist[i][j] << " "; } } std::cout << std::endl; } } int main() { int n = 4; // 结点数量 std::vector<std::vector<int>> graph = { {0, 5, INF, 10}, {INF, 0, 3, INF}, {INF, INF, 0, 1}, {INF, INF, INF, 0} }; floydWarshall(graph, n); return 0; } ``` 以上代码中,`graph` 是一个邻接矩阵表示的图,`INF` 表示两个结点之间不存在直接连接。`floydWarshall` 函数使用Floyd算法计算任意两结点的最短路径,并将结果存储在 `dist` 矩阵中。最后,我们打印出最短路径矩阵。 在 `main` 函数中,我们测试了一个示例图,并输出了最短路径矩阵。 希望这个代码示例能够帮助到你!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值