十五、最短路径问题:Dijkstra算法和floyd算法

一、Dijkstra

1、算法原理:
  • 指定起点s,引进两个集合S和U。
    S:是记录已求出最短路径的顶点(以及相应的最短路径长度)
    U:记录还未求出最短路径的顶点(以及该顶点到起点s的距离)。
  • Step1,S中只有起点s,从U中找出路径最短的顶点,将其加入到S中
  • Step2,更新U中的顶点和顶点对应的路径
  • 重复Step1和Step2 直到遍历完所有顶点

重复Step1,即更新S:从U中找出路径最短的顶点,加入到S中;
重复Step2,即更新U中的顶点和顶点对应的路径

比如我们想要计算从D到其他城市的最短距离:

Step1,S={D(0)}, U={A(∞),B(∞),C(3),E(4),F(∞),G(∞)}
在这里插入图片描述
Step2 通过C,更新从D到其他城市的最短距离

S={D(0),C(3)},
B(∞)=C(3)+10=13
F(∞)=C(3)+6=9
E(4)=C(3)+5=8(不更新)
U={A(∞),B(13),E(4),F(9),G(∞)}
在这里插入图片描述
Step3通过E,更新从D到其他城市的最短距离:
S={D(0),C(3),E(4)},
F(9)=E(4)+2=6
G(∞)=E(4)+8=12
U={A(∞),B(13),F(6),G(12)}
在这里插入图片描述
Step4通过F,更新从D到其他城市的最短距离
S={D(0),C(3),E(4),F(6)},
B(13)=F(6)+7=13 (不更新)
G(12)=F(6)+9=15 (不更新)
A(∞)=F(6)+16=22
U={A(22),B(13),G(12)}
在这里插入图片描述
Step5通过G,更新从D到其他城市的最短距离
S={D(0),C(3),E(4),F(6),G(12)},
A(22)=G(12)+14=26 (不更新)
U={A(22),B(13)}
在这里插入图片描述
Step6通过B,更新从D到其他城市的最短距离
S={D(0),C(3),E(4),F(6),G(12),B(13)},
A(22)=B(13)+12=25 (不更新)
U={A(22)}
在这里插入图片描述
最终,得到从D到其他城市的最短距离:
S={D(0),C(3),E(4),F(6),G(12),B(13),A(22)}
在这里插入图片描述

二、Floyd算法

在这里插入图片描述
初始的距离矩阵:
在这里插入图片描述

Floyd算法原理:
  • 使用了动态规划的思想,将图中顶点编号为1-n
  • 以两点之间最短距离经过的顶点中最大的顶点编号作为阶段,两点间目前算出的最短路径作为状态的值
  • 假设 为顶点编号i和j两点经过 最大顶点编号不超过k的最短路径长度,那么:
    在这里插入图片描述

代码样例:

import numpy as np
a = np.array([[0, 12, 999, 999, 999, 16, 14], 
			  [12, 0, 10,  999, 999, 7, 999],
			  [999,10, 0,  3,   5,   6, 999],
			  [999,999,3,  0,   4,  999,999],
			  [999,999,5,  4,   0,   2, 8],
			  [16, 7,  6, 999,  2,   0, 9],
			  [14, 999,999,999, 8,   9, 0]])
n=7
# 使用Floyd算法
for k in range(0, n):  # 阶段
	for i in range(0, n):  # 起点
		for j in range(0, n):  # 终点
			if a[i][k] + a[k][j] < a[i][j]:
				a[i][j] = a[i][k] + a[k][j]

# 输出结果
print('各城市之间的最短距离:', a)
print('城市D到其他城市的最短距离:', a[3])
使用networkx 里面的Dijkstra算法和Flody算法
import networkx as nx
import matplotlib.pyplot as plt

G=nx.read_gml('./football.gml')
nx.draw(G,with_labels=True) 
#plt.show() 
print(nx.shortest_path(G, source='Buffalo', target='Kent'))
print(nx.shortest_path(G, source='Buffalo', target='Rice'))

# Dijkstra算法
print(nx.single_source_dijkstra_path(G, 'Buffalo'))
print(nx.multi_source_dijkstra_path(G, {'Buffalo', 'Rice'}))
# Flody算法
print(nx.floyd_warshall(G, weight='weight'))

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值