[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: 使用队列,集合 标记初始结点已被发现,放入队列 ...
随机推荐
- Memcached 常见的问题
memcached是怎么工作的? Memcached的奇妙来自两阶段哈希(two-stage hash).Memcached就像一个巨大的.存储了非常多<key,value>对的哈希表. ...
- linux下Java运行时so文件的附加
将路径加入至 etc/ld.so.conf 中
- 探讨把一个元素从它所在的div 拖动到另一个div内的实现方法
故事背景: 接到一个新需求,要求用vue搞,主要是拖动实现布局,关键点有:单个组件拖动,一行多列里面的组件拖动, 单个组件可以拖入一行多列里, 单个组件的拖动好实现,关键是把一个组件拖动到另一个类似 ...
- 第9章 Docker Swarm 相关问题
9.1 我的 Docker 版本是 1.12,请问我跑的是一代 Swarm 还是二代 Swarm 啊? ……自己运行的 Swarm 怎么会连自己都不知道跑的是啥?
- Cocos2d-x Lua中网格动作
GridAction它有两个主要的子类Grid3DAction和TiledGrid3DAction,TiledGrid3DAction系列的子类中会有瓦片效果,如下图所示是Waves3D特效(Grid ...
- 创建String字符串的方式与区别
Java中创建一个字符串的方式有很多种,常见如: String s = new String("riqi"); String s = "riqi"; 但两者有什 ...
- 检验指定路径的文件是否存在ftp服务器中
import org.apache.commons.net.ftp.FTP;import org.apache.commons.net.ftp.FTPClient;import org.apache. ...
- 涉及到复制和二进制日志中的选项和变量-Replication and Binary Logging Options and Variables
在搭建复制中,有些参数需要我们留意,在这里罗列出来,供大家参考一下,以GTID为基础 --server-id server-id:这是一个全局的可动态调整的变量,取值范围为0-4294967295,也 ...
- 数据库之MySQL(二)
数据表基本 1.创建表 create table 表名( 列名 类型 是否可以为空, 列名 类型 是否可以为空)ENGINE=InnoDB DEFAULT CHARSET=utf8 是 ...
- Python Interpreter
在开始之前,我们先限定下python解释器的意思.当讨论Python的时候,解释器这个词可以用在不同的地方.有的时候,解释器指的是Python Interpreter,也就是你在命令行交互界面上输入p ...