[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: 使用队列,集合 标记初始结点已被发现,放入队列 ...
随机推荐
- 目前国际上所用云计算平台IaaS、PaaS、SaaS简介
随着云计算这个概念越来越为人所熟知,企业对云计算的重视程度也在日趋加深.这不仅是一种潮流,更体现了一种需求——数字化.现代化.科技化的整体需求.如今市场上云计算的运营商更是风起云涌,服务种类更是丰富繁 ...
- SlidingMenu官方实例分析5——FragmentChangeActivity
FragmentChangeActivity 这个类在OnCreate中依然判断了savedInstanceState,原因同上文一样,但是他这里使用了 这个方法是在转屏幕的时候,用于保存一些参数,比 ...
- JPA概述以及它和Hibernate之间的关系
http://www.cnblogs.com/Kevin-ZhangCG/p/8996491.html 一.JPA概述以及它和Hibernate之间的关系 1.1.Hibernate 概述 JPA J ...
- 【BZOJ1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+倍增
[BZOJ1977][BeiJing2010组队]次小生成树 Tree Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C ...
- SpringBoot使用H2内嵌数据库
1.驱动 我们知道,JDBC是JDK自带的接口规范,不同的数据库有不同的实现,只需要引入相应的驱动包即可. 在使用MySQL数据库时,引入的是MySQL驱动,相应的,使用H2数据库时,也需要引入H2驱 ...
- JavaScript中label与break配合使用
语法 label: statement 说明 label语句可以在代码中添加标签,以便将来使用.定义的标签可以在将来由break或continue语句引用.加标签的语句一般都要与for语句等循环语句配 ...
- 如何使用 stl 进行排列组合?
#include <iostream> #include <vector> #include <algorithm> //从 indexs 集合中选择 num 个元 ...
- 虚拟研讨会:如何设计好的RESTful API(转)
原文:虚拟研讨会:如何设计好的RESTful API? REST架构风格最初由Roy T. Fielding(HTTP/1.1协议专家组负责人)在其2000年的博士学位论文中提出.HTTP就是该架构风 ...
- “格式化HDFS后,HMaster进程启动失败”的问题解决
用 hadoop namenode -fromat 格式化后,用./start-hbase.sh 启动HMaster和HRegionServer,但是过几秒种后HMaster进程自动关闭,HRegio ...
- ubuntu ping响应慢的解决(转)
新装ubuntu之后感觉上网老是很慢,ping网站时每次ping指令都需要很久才能有响应,不过网络延迟却正常.后来发现是因为/etc/nsswitch.conf文件中hosts的配置有问题,做如下修改 ...