相关概念

对于一个图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源代码

# ----------------------------------------------
# Project: calculate diameter of graph
# Using floyd algorithm
# ---------------------------------------------- # define function: print shortest path
def getPath(i, j):
if i != j:
if path[i][j] == -1:
print('-', j+1, end='')
else:
getPath(i, path[i][j])
getPath(path[i][j], j) def printPath(i, j):
print(' Path:', i+1, end='')
getPath(i, j)
print() print('---------------- Program start ----------------')
# read data
flag = input('please input type of graph(1:directed '
'graph; 2:undirected graph): ')
vertex, edge = input('please input the number of '
'vertex and edge: ').strip().split() # initialized
flag = int(flag)
vertex = int(vertex)
edge = int(edge)
inf = 99999999
dis = [] # matrix of the shortest distance
path = [] # record the shortest path
for i in range(vertex):
dis += [[]]
for j in range(vertex):
if i == j:
dis[i].append(0)
else:
dis[i].append(inf)
for i in range(vertex):
path += [[]]
for j in range(vertex):
path[i].append(-1) # read weight information
print('please input weight info(v1 v2 w[v1,v2]): ')
for i in range(edge):
u, v, w = input().strip().split()
u, v, w = int(u)-1, int(v)-1, int(w)
if flag == 1:
dis[u][v] = w
elif flag == 2:
dis[u][v] = w
dis[v][u] = w
print('the weight matrix is:')
for i in range(vertex):
for j in range(vertex):
if dis[i][j] != inf:
print('%5d' % dis[i][j], end='')
else:
print('%5s' % '∞', end='')
print() # floyd algorithm
for k in range(vertex):
for i in range(vertex):
for j in range(vertex):
if dis[i][j] > dis[i][k] + dis[k][j]:
dis[i][j] = dis[i][k] + dis[k][j]
path[i][j] = k
print('===========================================') # output the result
print('output the result:')
if flag == 1:
for i in range(vertex):
for j in range(vertex):
if (i != j) and (dis[i][j] != inf):
print('v%d ----> v%d tol_weight:'
'%3d' % (i+1, j+1, dis[i][j]))
printPath(i, j)
if (i != j) and (dis[i][j] == inf):
print('v%d ----> v%d tol_weight:'
' ∞' % (i+1, j+1))
printPath(i, j) if flag == 2:
for i in range(vertex):
for j in range(i+1, vertex):
print('v%d <----> v%d tol_weight:'
'%3d' % (i+1, j+1, dis[i][j]), '', end='')
printPath(i, j)
print()
for i in range(vertex):
for j in range(vertex):
if dis[i][j] == inf:
dis[i][j] = 0
# max(max(dis)): the max item of two dimension matrix
print('>> the diameter of graph: %d <<' % max(max(dis)))
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. Android开发——初步

    一.项目结构介绍

  2. 推荐个WIN7下小巧的可转录声音的软件-Audio Record Wizard V6.99

    之前是XP上用的是 WaveCN 2.0.0.5,但这个软件好久没更新了,不支持WIN7 最终找到了Audio Record Wizard V6.99,尽管没 WaveCN 2.0.0.5好用,但也全 ...

  3. ASP.NET动态网站制作(29)-- 正则

    前言:继续讲框架,然后介绍正则的相关知识. 内容: 1.封装分页方法,方便以后调用:响应的CSS代码也可以封装. 2.WEB层里面的页面名称不要和model和dal里面的名称相同. 3.两个表联合查询 ...

  4. 怎样利用JDBC启动Oracle 自己主动追踪(auto trace)

    有时我们须要对运行SQL的详细运行过程做一个追踪分析,特别是在应用程序性能优化的时候.Oracle两个工具能够帮助我们做好性能分析,一个是SQL_TRACE,一个是SESSION_EVENT.SQL_ ...

  5. log4j日志文件乱码问题的解决方法

    近日在AIX上用log4j打印日志,出现乱码,经过努力解决问题. 症状:在默认语言非中文(或者说默认语言不支持中文的)的Windows.Linux.Unix上,用log4j打印日志,出现乱码,常见的就 ...

  6. Android无线测试之—UiAutomator UiSelector API介绍之一

    一. UiSelector类介绍: 1) UiSelector类说明: UiSelector代表一种搜索条件,可以在当前界面上查询和获取特定元素的句柄,当找到多余一个的匹配元素,则返回布局层次结构上第 ...

  7. IIS配置(持续更新中...)

    本文暂时适用于IIS7.5. IIS配置文件路径:"C:\Windows\System32\inetsrv\config\applicationHost.config" 1.sta ...

  8. log日志框架和LocationAwareLogger问题

    遇到了同样的问题, 我的解决办法是在pom.xml中增加如下配置,去除对于jcl-over-slf4j.jar的依赖. <exclusions>                <ex ...

  9. python函数回顾:all()

    描述 all() 函数用于判断给定的可迭代参数 iterable 中的所有元素,是否不为 0.''.False 或者 iterable 为空,如果是返回 True,否则返回 False. 如果是空元组 ...

  10. 我的Android进阶之旅------>Android中编解码学习笔记

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...