图论 邻接矩阵 详解 Python 描述 搜索:BFS DFS 最小生成树:Prim Kruskal

矩阵规则

对角线:元素 = 0
没有边: inf
有边: 权值

结构应该存在的东西

  • 是否为有向图和无向图
  • 顶点数
  • 边数
  • 存储矩阵(python:np.narray)
class Graph:
	def __init___(self):
		self.mat                 # 存储矩阵
		self.n                   # 存储边数 
		self.type                # 有向图和无向图
		self.s                   # 边数

遍历图 深度搜索 广度搜索

  1. 二者都需要存在访问标志,这样才可以知道这个点 是否 已经被访问过了!
  2. 二者都需要用某一个办法获取邻接的节点,然后用上面的访问标志才判断。

1. 深度搜索 DFS

visited = [False] * graph.n 
def DFS(graph, v):
	visited[v] = True
	for i in v.neighbors_node():
		if not visited[i]:
			DFS(graph, i)

2. 广度搜索 BFS

visited = [False] * graph.n 
def BFS(graph, v):
	q = Queue()        # 初始化队列
	visited[v] = True  # 访问过了
	q.put(v)           # 入队
	print(v)           # 输出顶点
	while not q.empty():
		i = q.put()    # 出列
		for j in i.neighbors_node():  # 获取的邻近节点是按照 从最近的顺序开始的
			if not visited[j]: 
				visited[j] =True
				q.put(j)
				print(j)	

路径的保存: 用栈;

3 应用:递归的使用。用来找一条简单路径。

visited = [False] * graph.n 
def Simple(graph, v, w, stack):
	visited[v] = True
	stack.push(v)
	for i in v.neighbors_node():
		if i == w:
			return True
		if not visited[i]:
			if Simple(graph, i, w, stack):
				return True
	stack.pop()

最核心的思想,就是一个搜索,把这个点的附近的全部顶点进行递归搜索;没用的路其实也就没戏了,而有用的路径则保留了下来。
函数最终的停止就是i == w 找到了最后的点。

4 应用:两个顶点的最短路径

广度搜索;
因为获得的邻点 是 从最近的开始排序的;

最小生成树 普里姆Prim 克鲁斯卡尔 Kruskal

1. 普里姆Prim

思想: 把图分开成为两部分,一部分是加入顶点集合的,另一部分是外面的。而且加入的除了顶点还有边。直到最后,顶点全部加载进去,一部分n-1个边被加载了进去。最后顶点和n-1个边 组合成为了 最小生成树。适合稠密图

2. 克鲁斯卡尔 Kruskal

思想:按照边的权值进行排序,然后选择一个最短的边。选择之后,要判断是否构成了圆环,如果构成者舍弃,如果没有则使用。边的排序,使用堆排序。环的判断使用了等价类和并查集的思想。适合稀疏图。

最短路径问题

一个源点到其他点的距离,一直更新;

1. 迪科斯特拉 Dijkstra 单源(一点到全部点)

思想: 类比Prim,也是分成了两个集合。一个是加入顶点集合的,剩下的是未加入的。一次只能加入一个点和一条边。也保证了是最短的路径。求最短路径的。

2. 弗洛伊德 Floyd 全源(任意两点)

核心算法:

Dk[i][j] = min{Dk[i][j],Dk[i][k]+Dk[k][j]}

k = 0,1,2,3,n-1
实际上就是寻找已经相连的两个点 是否有另外一个点,走另外一个点,可以有更加简短的路径。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东枫科技

打赏即可咨询本帖子的技术问题

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值