一.基础知识

 

有向图   无向图

以无向图为例:

邻接矩阵:

度矩阵(对角矩阵):

二.最小生成树

应用:将网络顶点看着城市,边看着城市之间通讯网,边的权重看着成本,根据最小生成树可以构建城市之间成本最低的通讯网.

1.kruskal(克鲁斯克尔)算法

2.普里姆算法(Prim算法)

求点与点之间的最小生成树

代码:

#coding:utf-8
"""
最小生成树
"""
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
from numpy import randomG = nx.Graph()
# Matrix = np.array(random.randint((5), size=(5, 5)))
# print('==Matrix:', Matrix)
# print(maps)
Matrix = np.array(  [[3, 4, 0, 2, 2],[4, 1, 0, 3, 4],[0, 0, 0, 4, 4],[2, 3, 4, 0, 3],[2, 4, 4, 3, 1]])
#实际在用的时候,只用了下三角矩阵
#构建无向图
for i in range(len(Matrix)):for j in range(len(Matrix)):if Matrix[i, j] != 0:G.add_edge(i, j)
nx.draw_networkx(G)
plt.title("G")
plt.show()class Graph(object):def __init__(self, Matrix):self.Matrix = Matrixself.nodenum = self.get_nodenum()self.edgenum = self.get_edgenum()def get_nodenum(self):return len(self.Matrix)def get_edgenum(self):count = 0for i in range(self.nodenum):  # 获取除去对角的下三角矩阵for j in range(i):# print('i,j', i, j)if self.Matrix[i][j] > 0 and self.Matrix[i][j] < 9999:count += 1return countdef kruskal(self):list = []if self.nodenum <= 0 or self.edgenum < self.nodenum - 1:return listedge_list = []for i in range(self.nodenum):  # 获取除去对角的下三角矩阵for j in range(i):if self.Matrix[i][j] < 9999:edge_list.append([i, j, self.Matrix[i][j]])print('==排序之前边的集合 edge_list:', edge_list)edge_list.sort(key=lambda a: a[2])  # 已经排好序的边集合print('==排序以后边的集合 edge_list:', edge_list)group = [[i] for i in range(self.nodenum)]  # 存储代表元列表print('存储代表元列表', group)for edge in edge_list:for i in range(len(group)):if edge[0] in group[i]:m = i#开始节点if edge[1] in group[i]:n = i#终止节点if m != n:# 合并联通分量 进行存储元列表更新list.append(edge)print('开始节点m,终止节点n:', m, n)group[m] = group[m] + group[n]group[n] = []print('==更新后的代表元列表:', group)return listdef prim(self):list = []if self.nodenum <= 0 or self.edgenum < self.nodenum - 1:return listselected_node = [0]candidate_node = [i for i in range(1, self.nodenum)]#候选节点# print('==candidate_node:', candidate_node)while len(candidate_node) > 0:begin, end, minweight = 0, 0, 9999for i in selected_node:for j in candidate_node:if self.Matrix[i][j] < minweight:minweight = self.Matrix[i][j]begin = i#存储开始节点end = j#存储终止节点list.append([begin, end, minweight])selected_node.append(end)#找到权重最小的边 加入可选节点candidate_node.remove(end)#候选节点被找到 进行移除return list
#
#
G = Graph(Matrix)
print('邻接矩阵为\n%s' % G.Matrix)
print('节点数据为%d,边数为%d\n' % (G.nodenum, G.edgenum))
print('------最小生成树kruskal算法------')
print(G.kruskal())print('------最小生成树prim算法')
print(G.prim())

三.最短路径:

1.Dijkstra(迪杰斯特拉)算法

Dijkstra算法用于解决单源最短路问题,所谓单源最短路就是指定一个起点,求出这个起点到其它所有点的最短路。本质就是依次让每个顶点作为起点,更新最短路的过程。

示例:求M到各个顶点的最短路径

             

先构建邻接矩阵Adjacent, 初始状态dist[1~n] = inf, dist[M]=0,顶点更新状态vst[1~n] = 0

以点M为起点:

dist[M] = 0    vst[M] = 0
dist[W] = inf  vst[W] = 0
dist[E] = inf  vst[E] = 0
dist[D] = inf  vst[D] = 0
dist[X] = inf  vst[X] = 0

找出dist中值最小且未被使用的点,发现dist[M]=0最小,且vst[M]=0,未被使用,故将M作为新的起点.
找出所有M可达的顶点,为X、W、E
dist[X]=inf > 0+10 ,更新dist[X]=10
dist[W]=inf > 0+5 ,更新dist[W]=5
dist[E]=inf > 0+8 ,更新dist[E]=8
M已被使用,vst[M]=1

dist[M] = 0    vst[M] = 1
dist[W] = 5    vst[W] = 0
dist[E] = 8    vst[E] = 0
dist[D] = inf  vst[D] = 0
dist[X] = 10   vst[X] = 0

依次遍历每个顶点........

Inf = float('inf')
# Dijkstra算法,就是依次让每个顶点作为起点,更新最短路的过程。
Adjacent = [[0, 10, 5, Inf, 8],[10, 0, 3, 1, Inf],[5, 3, 0, 9, 2],[Inf, 1, 9, 0, 6],[8, Inf, 2, 6, 0]]Src, Dst, N = 0, 4, 5def dijstra(adj, src, dst, n):dist = [Inf] * n  # 初始化为inf无穷大dist[src] = 0  # 起始点到起始点距离为0vst = [0] * n  # 记录已经确定的顶点prev = [0] * nwhile True:now = -1for u in range(n):  # 找到dist最小且vst=0的点作为起点if not vst[u] and (now == -1 or dist[u] < dist[now]):now = uprint('====now:', now)if now == -1:  # now未被更新,即表示所有顶点都被使用过,算法结束breakfor v in range(n):  # 遍历当前起点now能到达的所有点if dist[v] > dist[now] + adj[now][v]:  # 如果dist[v]大于dist[now] + adj[now][v] 则更新dist[v] = dist[now] + adj[now][v]prev[v] = nowprint('==dist:', dist)# assert 1==0vst[now] = 1  # 当前起点now已被使用过,vst[now]=1# print('===dist:', dist)# print('==prev:', prev)## print('==dist[dst]:', dist[dst])return dist, prevdist, prev = dijstra(Adjacent, Src, Dst, N)print('==dist,prev:', dist, prev)def construct_path(prev, index, path=[]):path = path + [prev[index]]if prev[index] == 0:#终止条件return pathnew_path = construct_path(prev, prev[index], path)return new_path
# res = construct_path(prev, 4,[4])
# print('==res:', res)
for i in range(len(prev)):path = construct_path(prev, i, [i])print('{}节点路径为:{}'.format(i, path))

2.Floyd(弗洛伊德)

本质任意两个节点最短路径是否经过此节点,用dp的思想来存储中间结果.

示例:

#Floyd(弗洛伊德)找最短路径 本质任意两个节点最短路径是否经过此节点
import numpy as np
Inf = float('inf')
DIS = [[0, 3, 8, Inf, -4],[Inf, 0, Inf, 1, 7],[Inf, 4, 0, Inf, Inf],[2, Inf, -5, 0, Inf],[Inf, Inf, Inf, 6, 0]]Direction = [[0, 1, 2, 3, 4],[0, 1, 2, 3, 4],[0, 1, 2, 3, 4],[0, 1, 2, 3, 4],[0, 1, 2, 3, 4]]
V = 5
#k就是是否要经过的节点,i就是开始节点,j就是终止节点
for k in range(V):for i in range(V):for j in range(V):if DIS[i][k] + DIS[k][j] < DIS[i][j]:DIS[i][j] = DIS[i][k] + DIS[k][j]Direction[i][j] = Direction[i][k]print('最终的距离矩阵{}'.format(np.array(DIS)))
print('方向矩阵{}'.format(np.array(Direction)))def construct_path(Direction, i, j, path=[]):path = path + [Direction[i][j]]if Direction[i][j] == j:#终止条件return pathnew_path = construct_path(Direction, Direction[i][j], j, path)return new_path#找到路径
for i in range(V):for j in range(V):path = construct_path(Direction, i, j, [i])print('{}--{}节点路径为:{}'.format(i, j, path))

最终的距离矩阵和方向矩阵,其中方向矩阵可以用来还原开始节点到终止节点的路径:

参考:

https://blog.csdn.net/weixin_43093481/article/details/82702176

https://www.bilibili.com/video/BV1q4411M7r9?from=search&seid=4042347737055062965

图论基础知识--最小生成树算法kruskal(克鲁斯克尔)和普里姆算法(Prim算法);最短路径算法Dijkstra(迪杰斯特拉)和Floyd(弗洛伊德)相关推荐

  1. 图论最短距离(Shortest Path)算法动画演示-Dijkstra(迪杰斯特拉) 和 Floyd(弗洛伊德)

    视 频 地 址 : https://www.bilibili.com/video/BV1q4411M7r9?from=search&seid=16626092504824296903 Dijk ...

  2. 最短路径之Dijkstra(迪杰斯特拉)算法(无向图)

    简介      Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.由for循环可知,其时间 ...

  3. 最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现(C/C++)

    Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法能得出最短路径的最优 ...

  4. [转]最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现

    最短路径算法-Dijkstra(迪杰斯特拉)算法分析与实现(C/C++) Dijkstra算法 ----------- 最后更新时间:2011.9.25 ----------- Dijkstra(迪杰 ...

  5. 图论(迪杰斯特拉,Floyd,bellman,spfa)

    对图论和搜索的学习感想 Dijkstra 迪杰斯特拉求最短路的暴力的思路是三重循环去更新所有点到起点的最短距离. 首先先初始化让第一个点到自己的距离是0即: dist[1]=0; 然后在省下的点中找到 ...

  6. MATLAB轻松绘制地图路线——Dijkstra(迪杰斯特拉)算法最短路径规划

    文章目录 1. 地图绘制 2. 计算各节点之间的距离 3. Dijkstra(迪杰斯特拉)算法 4. 根据计算出的距离利用Dijkstra(迪杰斯特拉)算法找出指定节点之间的最短路径 工程文件(可直接 ...

  7. JavaScript实现dijkstra迪杰斯特拉算法(附完整源码)

    JavaScript实现dijkstra迪杰斯特拉算法 PriorityQueue完整源代码 MinHeap.js完整源代码 Heap.js完整源代码 Comparator.js完整源代码 dijks ...

  8. C++实现Dijkstra(迪杰斯特拉)算法(附完整源码)

    C++Dijkstra迪杰斯特拉算法的实现 C++Dijkstra(迪杰斯特拉)算法的完整源码(定义,实现,main函数测试) C++Dijkstra(迪杰斯特拉)算法的完整源码(定义,实现,main ...

  9. C语言实现Dijkstra(迪杰斯特拉)算法(附完整源码)

    Dijkstra迪杰斯特拉 Graph结构体定义 迪杰斯特拉算法完整源码(定义,实现,main函数测试) Graph结构体定义 struct Graph {int vertexNum;int **ed ...

最新文章

  1. mysql维护索引,mysql 索引优化
  2. 在龙芯上调试CoreCLR
  3. python字符串是用双引号括起来的_用python连接字符串列表并用引号将每个字符串括起来...
  4. JAVA中基本类型Boolean占几个字节
  5. @SuppressWarnings(resource)
  6. window10保存文件时提示联系管理员_东芝2000AC扫描文件到远程域共享服务器
  7. 链表的游标(cursor)实现
  8. VMD如何确定分解层数(一):最优变分模态分解(OVMD)---VMD分解的基础上确定分解层数和更新步长
  9. 6. 机器人正运动学---齐次变换矩阵的三种解读
  10. 聚类 之 MeanShift
  11. 设置共享后其他计算机无法访问,电脑设置了文件共享其他电脑无法访问该怎么处理...
  12. 百家讲坛之易中天品三国MP3全集
  13. 管中窥豹之淘宝大数据平台
  14. 【BC260Y】 AT指令接入移动oneNet平台流程
  15. 安卓调用系统相机拍照并且显示在ImageView上
  16. 数据洪流时代,企业转型需要修建自己的“都江堰”
  17. 江苏省盐城中学信息竞赛队(YZOI)队规
  18. 教你一招利用python在网上接单赚钱,月薪过万太香了
  19. 【转载】HTML之图像的处理(六)
  20. 面试题:为什么索引要使用B+树而不使用其他索引?以及B+树为什么更矮胖

热门文章

  1. soapui返回值类型都有哪些_法兰的类型都有哪些以及法兰的设计
  2. 数据缺失、混乱、重复怎么办?最全数据清洗指南让你所向披靡
  3. 戴着口罩也要开心过年吖!
  4. Spring Cloud Alibaba基础教程:Sentinel Dashboard中修改规则同步到Apollo
  5. AutoPep8-----Pycharm自动排版工具
  6. 新鲜出炉!大规模神经网络最新综述!
  7. day21 面向对象之继承和组合
  8. ListObject 多条件去重
  9. Java中使用队列Queue
  10. 【will】JS去字符串首尾空格