相关概念

对于一个图G=(V, E),求图中两点u, v间最短路径长度,称为图的最短路径问题。最短路径中最长的称为图的直径

其中,求图中确定的某两点的最短路径算法,称为单源最短路径算法。求图中任意两点间的最短路径算法,称为多源最短路径算法。

常用的路径算法有:

  • Dijkstra算法
  • SPFA算法\Bellman-Ford算法
  • Floyd算法\Floyd-Warshall算法
  • Johnson算法

其中最经典的是Dijkstra算法和Floyd算法。Floyd算法是多源最短路径算法,可以直接求出图中任意两点间的距离,因此只要取其中最大的就可以得到图的直径。

Floyd算法

算法思想

假设Dis(i,j)为节点u到节点v的最短路径的距离(最短路径长度),对于每一个节点k,检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,说明从i到k再到j的路径比i直接到j的路径短,便记录Dis(i,j) = Dis(i,k) + Dis(k,j)。因此,当遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。

算法特点

  • 使用了动态规划思想
  • 可以计算无向图或有向图
  • 核心代码简短(五行)
  • 可以一次性计算出任意两点间的距离
  • 算法复杂度O(n^3),是一个算法

一个关键性问题

在判断Dis(i,k) + Dis(k,j) < Dis(i,j)这个公式时,如果经过k的距离更短就选择k,但是这能否保证此时Dis(i,k)和Dis(k,j)已经取得了最小值呢?

答案是肯定的,可以用数学归纳法证明,参考这篇博客

示例

待求直径的图G

程序输入

2(表示无向图)

8 9 (表示8个顶点,9条边)

1 2 5 (表示顶点1和顶点2之间的距离权重是5)

... ...

程序输出

(邻接矩阵,矩阵元素M[i][j]表示顶点Vi与Vj间的距离)

(各个顶点间的最短路径以及路径长度,对于此例,顶点V4与V6或V8间的距离都是10,是距离最远的两个顶点对)

(此图的直径)

Python源代码

  1. # ----------------------------------------------
  2. # Project: calculate diameter of graph
  3. # Using floyd algorithm
  4. # ----------------------------------------------
  5. # define function: print shortest path
  6. def getPath(i, j):
  7. if i != j:
  8. if path[i][j] == -1:
  9. print('-', j+1, end='')
  10. else:
  11. getPath(i, path[i][j])
  12. getPath(path[i][j], j)
  13. def printPath(i, j):
  14. print(' Path:', i+1, end='')
  15. getPath(i, j)
  16. print()
  17. print('---------------- Program start ----------------')
  18. # read data
  19. flag = input('please input type of graph(1:directed '
  20. 'graph; 2:undirected graph): ')
  21. vertex, edge = input('please input the number of '
  22. 'vertex and edge: ').strip().split()
  23. # initialized
  24. flag = int(flag)
  25. vertex = int(vertex)
  26. edge = int(edge)
  27. inf = 99999999
  28. dis = [] # matrix of the shortest distance
  29. path = [] # record the shortest path
  30. for i in range(vertex):
  31. dis += [[]]
  32. for j in range(vertex):
  33. if i == j:
  34. dis[i].append(0)
  35. else:
  36. dis[i].append(inf)
  37. for i in range(vertex):
  38. path += [[]]
  39. for j in range(vertex):
  40. path[i].append(-1)
  41. # read weight information
  42. print('please input weight info(v1 v2 w[v1,v2]): ')
  43. for i in range(edge):
  44. u, v, w = input().strip().split()
  45. u, v, w = int(u)-1, int(v)-1, int(w)
  46. if flag == 1:
  47. dis[u][v] = w
  48. elif flag == 2:
  49. dis[u][v] = w
  50. dis[v][u] = w
  51. print('the weight matrix is:')
  52. for i in range(vertex):
  53. for j in range(vertex):
  54. if dis[i][j] != inf:
  55. print('%5d' % dis[i][j], end='')
  56. else:
  57. print('%5s' % '∞', end='')
  58. print()
  59. # floyd algorithm
  60. for k in range(vertex):
  61. for i in range(vertex):
  62. for j in range(vertex):
  63. if dis[i][j] > dis[i][k] + dis[k][j]:
  64. dis[i][j] = dis[i][k] + dis[k][j]
  65. path[i][j] = k
  66. print('===========================================')
  67. # output the result
  68. print('output the result:')
  69. if flag == 1:
  70. for i in range(vertex):
  71. for j in range(vertex):
  72. if (i != j) and (dis[i][j] != inf):
  73. print('v%d ----> v%d tol_weight:'
  74. '%3d' % (i+1, j+1, dis[i][j]))
  75. printPath(i, j)
  76. if (i != j) and (dis[i][j] == inf):
  77. print('v%d ----> v%d tol_weight:'
  78. ' ∞' % (i+1, j+1))
  79. printPath(i, j)
  80. if flag == 2:
  81. for i in range(vertex):
  82. for j in range(i+1, vertex):
  83. print('v%d <----> v%d tol_weight:'
  84. '%3d' % (i+1, j+1, dis[i][j]), '', end='')
  85. printPath(i, j)
  86. print()
  87. for i in range(vertex):
  88. for j in range(vertex):
  89. if dis[i][j] == inf:
  90. dis[i][j] = 0
  91. # max(max(dis)): the max item of two dimension matrix
  92. print('>> the diameter of graph: %d <<' % max(max(dis)))
  93. print('-------------- Program end ----------------')

Reference

最短路径_百度百科

最短路径—Dijkstra算法和Floyd算法

最短路径问题---Floyd算法详解 - CSDN博客

Floyd算法(记录路径) - CSDN博客

[Python] 弗洛伊德(Floyd)算法求图的直径并记录路径的更多相关文章

  1. 图的最短路径---弗洛伊德(Floyd)算法浅析

    算法介绍 和Dijkstra算法一样,Floyd算法也是为了解决寻找给定的加权图中顶点间最短路径的算法.不同的是,Floyd可以用来解决"多源最短路径"的问题. 算法思路 算法需要 ...

  2. 最短路径 - 弗洛伊德(Floyd)算法

    为了能讲明白弗洛伊德(Floyd)算法的主要思想,我们先来看最简单的案例.图7-7-12的左图是一个简单的3个顶点的连通网图. 我们先定义两个二维数组D[3][3]和P[3][3], D代表顶点与顶点 ...

  3. _DataStructure_C_Impl:Floyd算法求有向网N的各顶点v和w之间的最短路径

    #include<stdio.h> #include<stdlib.h> #include<string.h> typedef char VertexType[4] ...

  4. 数据结构与算法——弗洛伊德(Floyd)算法

    介绍 和 Dijkstra 算法一样,弗洛伊德(Floyd)算法 也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978 年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特 ...

  5. C# 弗洛伊德(Floyd)算法

    弗洛伊德(Floyd)算法 主要是用于计算图中所有顶点对之间的最短距离长度的算法,如果是要求某一个特定点到图中所有顶点之间的最短距离可以用;        ;    ;    ;            ...

  6. 【POJ - 2139】Six Degrees of Cowvin Bacon (Floyd算法求最短路)

    Six Degrees of Cowvin Bacon Descriptions 数学课上,WNJXYK忽然发现人缘也是可以被量化的,我们用一个人到其他所有人的平均距离来量化计算. 在这里定义人与人的 ...

  7. Kruscal算法求图的最小生成树

    Kruscal算法求图的最小生成树 概述   和Prim算法求图的最小生成树一样,Kruscal算法求最小生成树也用到了贪心的思想,只不过前者是贪心地选择点,后者是贪心地选择边.而且在算法的实现中,我 ...

  8. Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例

    本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...

  9. Python数据结构与算法之图的广度优先与深度优先搜索算法示例

    本文实例讲述了Python数据结构与算法之图的广度优先与深度优先搜索算法.分享给大家供大家参考,具体如下: 根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 ...

随机推荐

  1. Memcached 常见的问题

    memcached是怎么工作的? Memcached的奇妙来自两阶段哈希(two-stage hash).Memcached就像一个巨大的.存储了非常多<key,value>对的哈希表. ...

  2. linux下Java运行时so文件的附加

    将路径加入至 etc/ld.so.conf 中

  3. 探讨把一个元素从它所在的div 拖动到另一个div内的实现方法

    故事背景: 接到一个新需求,要求用vue搞,主要是拖动实现布局,关键点有:单个组件拖动,一行多列里面的组件拖动,  单个组件可以拖入一行多列里, 单个组件的拖动好实现,关键是把一个组件拖动到另一个类似 ...

  4. 第9章 Docker Swarm 相关问题

    9.1 我的 Docker 版本是 1.12,请问我跑的是一代 Swarm 还是二代 Swarm 啊? ……自己运行的 Swarm 怎么会连自己都不知道跑的是啥?

  5. Cocos2d-x Lua中网格动作

    GridAction它有两个主要的子类Grid3DAction和TiledGrid3DAction,TiledGrid3DAction系列的子类中会有瓦片效果,如下图所示是Waves3D特效(Grid ...

  6. 创建String字符串的方式与区别

    Java中创建一个字符串的方式有很多种,常见如: String s = new String("riqi"); String s = "riqi"; 但两者有什 ...

  7. 检验指定路径的文件是否存在ftp服务器中

    import org.apache.commons.net.ftp.FTP;import org.apache.commons.net.ftp.FTPClient;import org.apache. ...

  8. 涉及到复制和二进制日志中的选项和变量-Replication and Binary Logging Options and Variables

    在搭建复制中,有些参数需要我们留意,在这里罗列出来,供大家参考一下,以GTID为基础 --server-id server-id:这是一个全局的可动态调整的变量,取值范围为0-4294967295,也 ...

  9. 数据库之MySQL(二)

    数据表基本 1.创建表 create table 表名(   列名  类型  是否可以为空,   列名  类型  是否可以为空)ENGINE=InnoDB DEFAULT CHARSET=utf8 是 ...

  10. Python Interpreter

    在开始之前,我们先限定下python解释器的意思.当讨论Python的时候,解释器这个词可以用在不同的地方.有的时候,解释器指的是Python Interpreter,也就是你在命令行交互界面上输入p ...