[Python] 弗洛伊德(Floyd)算法求图的直径并记录路径
相关概念
对于一个图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)算法求图的直径并记录路径的更多相关文章
- 图的最短路径---弗洛伊德(Floyd)算法浅析
算法介绍 和Dijkstra算法一样,Floyd算法也是为了解决寻找给定的加权图中顶点间最短路径的算法.不同的是,Floyd可以用来解决"多源最短路径"的问题. 算法思路 算法需要 ...
- 最短路径 - 弗洛伊德(Floyd)算法
为了能讲明白弗洛伊德(Floyd)算法的主要思想,我们先来看最简单的案例.图7-7-12的左图是一个简单的3个顶点的连通网图. 我们先定义两个二维数组D[3][3]和P[3][3], D代表顶点与顶点 ...
- _DataStructure_C_Impl:Floyd算法求有向网N的各顶点v和w之间的最短路径
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef char VertexType[4] ...
- 数据结构与算法——弗洛伊德(Floyd)算法
介绍 和 Dijkstra 算法一样,弗洛伊德(Floyd)算法 也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978 年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特 ...
- C# 弗洛伊德(Floyd)算法
弗洛伊德(Floyd)算法 主要是用于计算图中所有顶点对之间的最短距离长度的算法,如果是要求某一个特定点到图中所有顶点之间的最短距离可以用; ; ; ; ...
- 【POJ - 2139】Six Degrees of Cowvin Bacon (Floyd算法求最短路)
Six Degrees of Cowvin Bacon Descriptions 数学课上,WNJXYK忽然发现人缘也是可以被量化的,我们用一个人到其他所有人的平均距离来量化计算. 在这里定义人与人的 ...
- Kruscal算法求图的最小生成树
Kruscal算法求图的最小生成树 概述 和Prim算法求图的最小生成树一样,Kruscal算法求最小生成树也用到了贪心的思想,只不过前者是贪心地选择点,后者是贪心地选择边.而且在算法的实现中,我 ...
- Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...
- Python数据结构与算法之图的广度优先与深度优先搜索算法示例
本文实例讲述了Python数据结构与算法之图的广度优先与深度优先搜索算法.分享给大家供大家参考,具体如下: 根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 ...
随机推荐
- JAVA中BufferedReader设置编码的必要性
实验环境 Myeclipse 默认编码 UTF-8 先看两种读文件的方式: 方式一: InputStreamReader fReader = new InputStreamReader(new Fil ...
- python3 - 闭包
# 定义一个函数def test(number): # 在函数内部再定义一个函数,并且这个函数用到外边函数的变量, # 那么将这个函数以及用到的一些变量称之为 闭包. def text_in(numb ...
- @Resource 注解
@Resource 注解被用来激活一个命名资源(named resource)的依赖注入,在JavaEE应用程序中,该注解被典型地转换为绑定于JNDI context中的一个对象. Spring确实支 ...
- Docker Metasploit Framework
https://hub.docker.com/r/usertaken/metasploit-framework/ docker pull usertaken/metasploit-framework ...
- delphi局域网Ping各主机方法及设置本地ip方法
1. 首先引用winsock单元 function PingHost(HostIP: String): Boolean; type PIPOptionInformation=^TIPOptionInf ...
- Struts之Token机制
Struts的Token(令牌)机制能够很好的解决表单重复提交的问题,基本原理是:服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配.在处理完该请求 ...
- /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15"" not found
解决错误 呈现该错误的原因是当前的GCC版本中,没有GLIBCXX_3.4.15,须要安装更高版本. 我们可以输入:strings /usr/lib/libstdc++.so.6 | grep GLI ...
- 003-诠释 Java 工程师【一】
一.基础篇 1.面向对象的三大特性 继承.封装.多态 什么是继承? ①继承是面向对象程序设计能够提高软件开发效率的重要原因之一. ②继承是具有传递性的,就像现实中孙子不仅长得像爸爸而且还像他爷爷. ③ ...
- JavaWeb—监听器Listener
1.简介 Listener是Servlet的监听器,Servlet 监听器用于监听一些重要事件的发生,监听器对象在事情发生前.发生后可以做一些必要的处理. JavaWeb里面的listener是通过观 ...
- Oracle学习笔记—数据库,实例,表空间,用户、表之间的关系
之前一直使用的关系型数据库是Mysql,而新公司使用Oracle,所以最近从网上搜集了一些资料,整理到这里,如果有不对的地方,欢迎大家讨论. 基本概念: 数据库:Oracle 数据库是数据的物理存储. ...