最短路径(dijkstra 与 Floyd)
1. 如何建图?
要跑最短路,首先要有图 ——鲁迅
常用的存储方法有两种,分别是邻接矩阵(用二维数组表示边)和邻接表(模拟链表表示边)两种,他们各有不同的优势和不足:
| 邻接矩阵 | 邻接表 | |
|---|---|---|
| 使用范围 | 稠密图 | 主要是稀疏图 |
| 空间耗费 | n^2(n节点数) | 理论上是 e( e为边条数) |
| 实现方式 | 二维数组 | 存储每个节点相连的节点和边权值 |
通常来讲,在数据范围足够小时,我们采用邻接矩阵,而数据范围大时采用邻接表
邻接矩阵实现:
无权图:
g[x][y]=1 #g[x][y]=1表示x到y有一条边连接
#g[y][x]=1 #去掉注释后是无向图
带权图:
g[x][y]=w #g[x][y]=w表示x到y有一条权值为w的边
#g[y][x]=w #去掉注释后是无向图
2. Floyd
多源最短路算法,用邻接矩阵存储,可以处理负边权,但不能处理负环
多源最短路就是说只要跑一次,任意两点的最短路都能求啦( ̄︶ ̄),而其他单源最短路跑一次只能得出一个点到其他点的最短路
用邻接矩阵存最短路( dis[i][j]表示 i到j的最短距离)开一个三重循环(!)
外层枚举中间点,中间枚举起点,内层枚举终点,当三个点互不相同时进行松弛操作,如果经过中间点之后的路程和比原路程短,就更新距离,一轮过后,我们得到了一个新的矩阵,然后我们把中间点换成下一个点,再次松弛,的到一个新的矩阵,执行 n 次之后,第 n个矩阵就是我们的答案啦
#提前将邻接矩阵存在dis数组里,其他不连通的地方初始化成无穷大
for k in range(n): #枚举中间点
for i in range(n): #枚举起点
if(i!=k): #节省时间,如果一样就不往下走
for j in range(n): #枚举终点
if(i!=j and j!=k): #继续判断,如果有一样的就不往下走
dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j])
3. Dijkstra
单源最短路径
将所有节点分成两类:已确定从起点到当前点的最短路长度的节点,以及未确定从起点到当前点的最短路长度的节点(下面简称「未确定节点」和「已确定节点」)。
每次从「未确定节点」中取一个与起点距离最短的点,将它归类为「已确定节点」,并用它「更新」从起点到其他所有「未确定节点」的距离。直到所有点都被归类为「已确定节点」。
用节点 A「更新」节点 B 的意思是,用起点到节点 A 的最短路长度加上从节点 A 到节点 B 的边的长度,去比较起点到节点 B 的最短路长度,如果前者小于后者,就用前者更新后者。这种操作也被叫做「松弛」。
这里暗含的信息是:每次选择「未确定节点」时,起点到它的最短路径的长度可以被确定。
——力扣(LeetCode)
def dijkstra(u):
#初始化起点 u 到每一个点的距离
for k in range(n):
dis[k] = g[u][k]
print("起点到其他节点的初始距离:",dis)
used[u] = 1
for k in range(n):
minv = float('inf')
#在未确定节点中找与起点距离最短的
for i in range(n):
if not used[i] and dis[i] < minv:
minv = dis[i]
temp = i
#中转位置, 变为已确定节点,更新距离
used[temp] = 1
for i in range(n):
if g[temp][i]+dis[temp] < dis[i]:
dis[i] = g[temp][i]+dis[temp]
print("第 {} 次迭代,起点到其他节点的距离:{}".format(k,dis))
测试下
with open("path.txt",'r') as f:
n = int(f.readline())
weights = f.readlines()
print("顶点数:",n)
dis = [0]*n
used = [0]*n
# 定义邻接矩阵存储图
g = [[0]*n for _ in range(n)]
for u in range(n):
for v in range(n):
g[u][v] = int(weights[u].strip().split()[v])
print("邻接矩阵:",g)
# g[u][v] = g[v][u] = w # 创建图,节点间没有连接赋值为 无穷大
dijkstra(0)
执行结果:
起点到其他节点的初始距离: [65535, 33, 21, 26, 65535, 65535, 65535, 65535]
第 0 次迭代,起点到其他节点的距离:[42, 33, 21, 26, 65535, 42, 65535, 65535]
第 1 次迭代,起点到其他节点的距离:[42, 33, 21, 26, 62, 42, 96, 117]
第 2 次迭代,起点到其他节点的距离:[42, 33, 21, 26, 62, 42, 96, 117]
第 3 次迭代,起点到其他节点的距离:[42, 33, 21, 26, 62, 42, 71, 117]
第 4 次迭代,起点到其他节点的距离:[42, 33, 21, 26, 62, 42, 71, 117]
第 5 次迭代,起点到其他节点的距离:[42, 33, 21, 26, 62, 42, 71, 117]
第 6 次迭代,起点到其他节点的距离:[42, 33, 21, 26, 62, 42, 71, 117]
第 7 次迭代,起点到其他节点的距离:[42, 33, 21, 26, 62, 42, 71, 117]
附上数据
8
65535 33 21 26 65535 65535 65535 65535 65535
33 0 65535 27 30 65535 65535 65535 65535
21 65535 0 22 65535 21 65535 65535 65535
26 27 22 019 36 33 70 91
65535 30 65535 190 65535 41 64 80
65535 65535 21 36 65535 0 29 65535 65535
65535 65535 65535 33 41 290 22 65535
65535 65535 65535 70 64 65535 22 0 42
references:
https://www.cnblogs.com/Staceyacm/p/10782094.html
https://www.luogu.com.cn/blog/FrozaFerrari/xue-tu-lun-ni-zhen-di-liao-xie-zui-duan-lu-ma-post
https://www.bilibili.com/video/BV1q4411M7r9/?spm_id_from=333.788.videocard.1
最短路径(dijkstra 与 Floyd)的更多相关文章
- 最短路径—Dijkstra算法和Floyd算法
原文链接:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最后边附有我根据文中Dijkstra算法的描述使用jav ...
- 最短路径—Dijkstra算法和Floyd算法【转】
本文来自博客园的文章:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html Dijkstra算法 1.定义概览 Dijk ...
- 单源最短路径Dijkstra算法,多源最短路径Floyd算法
1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...
- 图的最短路径——dijkstra算法和Floyd算法
dijkstra算法 求某一顶点到其它各个顶点的最短路径:已知某一顶点v0,求它顶点到其它顶点的最短路径,该算法按照最短路径递增的顺序产生一点到其余各顶点的所有最短路径. 对于图G={V,{E}};将 ...
- 最短路径——Dijkstra算法和Floyd算法
Dijkstra算法概述 Dijkstra算法是由荷兰计算机科学家狄克斯特拉(Dijkstra)于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图(无 ...
- 最小生成树(prime算法 & kruskal算法)和 最短路径算法(floyd算法 & dijkstra算法)
一.主要内容: 介绍图论中两大经典问题:最小生成树问题以及最短路径问题,以及给出解决每个问题的两种不同算法. 其中最小生成树问题可参考以下题目: 题目1012:畅通工程 http://ac.jobdu ...
- 【转载】最短路径—Dijkstra算法和Floyd算法
注意:以下代码 只是描述思路,没有测试过!! Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始 ...
- 最短路径-Dijkstra算法与Floyd算法
一.最短路径 ①在非网图中,最短路径是指两顶点之间经历的边数最少的路径. AE:1 ADE:2 ADCE:3 ABCE:3 ②在网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径 ...
- 图的最短路径:Dijkstra 和 Floyd
//最短路径 /* dijkstra Dijkstra(迪杰斯特拉)算法的核心思想是贪心策略+动态规划 http://www.programgo.com/article/4721147659/ Dij ...
- (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍
这一篇博客以一些OJ上的题目为载体.整理一下最短路径算法.会陆续的更新... 一.多源最短路算法--floyd算法 floyd算法主要用于求随意两点间的最短路径.也成最短最短路径问题. 核心代码: / ...
随机推荐
- 新鲜整理的Java学习大礼包!!锵锵锵锵~
第一部分:Java视频资源! 前端 HTML5新元素之Canvas详解 https://www.bilibili.com/video/BV1TE41177TE HTML5之WebStorage详解 h ...
- python7.2抛出自定义异常
pwd="123456"if len(pwd)<8: ex= Exception("密码不能低于8位数!")#自定义异常 raise ex #抛出自定义的 ...
- Spring IoC是如何进行依赖注入的
依赖注入(DI) DI(Dependency Injection),Spring IoC 不是一种技术,而是一种思想,通过这种思想,能够指导我们设计出松耦合的程序代码.而Spring IoC这个思想的 ...
- 每日一道 LeetCode (8):删除排序数组中的重复项和移除元素
每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...
- JS 执行机制笔记
js同步和异步同步 前一个任务结束以后再执行下面一个任务,程序的执行顺序与任务的排列顺序是一致的 同步任务都在主线程上执行,形成一个执行线 异步 前一个任务没结束之前程序还可以执行别的任务 j ...
- 第一次MySQL的SQL注入实验
测试平台:https://www.mozhe.cn/news/detail/324 上完SQL注入的第一节课过来对着笔记一步一步来做.. 1.首页面上没有id=XXX的东西,看见“平台维护通知”,点开 ...
- 【计算机算法设计与分析】——NP
时间复杂度 时间复杂度并不是表示一个程序解决问题需要花多少时间,而是当问题规模扩大后,程序需要的时间长度增长得有多快.也就是说,对于高速处理数据的计算机来说,处理某一个特定数据的效率不能衡量一个程序的 ...
- Oracle 存储过程 批量插入测试数据
有时候需要做DB的效率测试时,需要模拟大量数据.可以根据一条原始数据,通过执行存储过程拷贝出大量数据: CREATE OR REPLACE PROCEDURE proc_msw_strsql IS i ...
- python中1 is True 的结果为False,is判断与==判断的区别
python中1 is True 的结果为False,而1 == True的结果为True. python中True的数值就是1,那为什么1 is True 的结果为False呢? 因为is判断和== ...
- [noip2002] 产生数
题目描述 给出一个整数 n (n<1030)和 k 个变换规则 (k < 15) . 规则: 一位数可变换成另一个一位数: 规则的右部不能为零. 例如:n = 234 .有规则( k=2 ...