图的介绍以及Python实现

一 、图相关概念介绍

1 顶点

顶点(也称“节点”)是图的基本部分。一个顶点也可能有额外的信息,将其称为“有效载荷”。

2 边

边(也称“弧”)是图的另一个基本部分。边连接两个顶点,即他们之间存在关系。边可以是单向,也可以是双向。如果图中的边都是单向的,称该图为有向图

3 权重

边可以通过加权的形式表示从一个顶点到另一个顶点的成本。

4 图的数学定义

G = < V , E > G=<V,E> G=<V,E>, V V V代表顶点的集合, E E E代表边的集合。每条边是一个元组 ( v , w ) (v,w) (v,w),其中 w , v ∈ V w,v\in V w,vV,可以在元组中添加一维数据用来表示顶点相连边的权重。

路径

图中的路径是由边连接的顶点序列。定义一个路径为 w 1 , w 2 , . . . , w n w_1,w_2,...,w_n w1,w2,...,wn,使得 ( w i , w i + 1 ) ∈ E , 1 ≤ i ≤ n − 1 (w_i,w_{i+1})\in E,1 ≤ i ≤ n-1 (wi,wi+1)E,1in1. 未加权路径长度是路径中的边的数目,具体是 n − 1 n−1 n1 ;加权路径长度是路径中所有边的权重的总和。

循环有向图

循环有向图中的循环是指在同一顶点开始和结束的路径。没有循环的有向图称为有向无环图或 DAG 。

二 、图抽象数据类型

Graph()创建一个新的空图。
addVertex(vert)向图中添加一个顶点实例。
addEdge(fromVert, toVert)向连接两个顶点的图添加一个新的有向边。
addEdge(fromVert, toVert, weight)向连接两个顶点的图添加一个新的加权的有向边。
getVertex(vertKey)在图中找到名为 vertKey 的顶点。
getVertices()返回图中所有顶点的列表。
in 返回 True 如果 vertex in graph 里给定的顶点在图中,否则返回False。

1.邻接矩阵

邻接矩阵即一个二维矩阵。每个行和列表示图中的顶点。存储在行 v v v 和列 w w w 的交叉点处的单元中的值表示是否存在从顶点 v v v 到顶点 w w w 的边。 当两个顶点通过边连接时,我们说它们相邻。单元格中的值表示从顶点 v v v 到顶点 w w w 的边的权重。

邻接矩阵的优点是简单。对于小图,很容易看到哪些节点连接到其他节点。 然而,注意矩阵中的大多数单元格是空的,我们说这个矩阵是“稀疏的”,这样会浪费内存,所以并不是一种有效的存储方式。

2.邻接表

实现稀疏连接图的更高效的方法是使用邻接表。在邻接表实现中,保存 Graph 对象中的所有顶点,然后图中的每个顶点对象维护连接到的其他顶点。 使用字典完成顶点类的实现,其中字典键是顶点,值是权重。

邻接表避免了邻接矩阵表示稀疏图浪费内存的缺点。

3.邻接表Python实现

创建两个类 Graph 和 Vertex 。Vertex中的每个顶点通过字典 connectedTo 来跟踪它连接的顶点和每个边的权重。

class Vertex:
	def __init__(self,key):
		self.id = key
		self.connectedTo = {}

	def addNeighbor(self,nbr,weight=0):
		self.connectedTo[nbr] = weight

	def __str__(self):
		return str(self.id) + ' connectedTo: '+ str([x.id for x in self.connectedTo])

	def getConnections(self):
		return self.connectedTo.keys()

	def getId(self):
		return self.id

	def getWeight(self,nbr):
		return self.connectedTo[nbr]
class Graph:
	def __init__(self):
		self.vertList = {}
		self.numVertices = 0

	def addVertex(self,key):
		self.numVertices = self.numVertices + 1
		newVertex = Vertex(key)
		self.vertList[key] = newVertex
		return newVertex

	def getVertex(self,n):
		if n in self.vertList:
			return self.vertList[n]
		else:
			return None

	def __contains__(self,n):
		return n in self.vertList

	def addEdge(self,f,t,cost=0):
		if f not in self.vertList:
			nv = self.addVertex(f)
		if t not in self.vertList:
			nv = self.addVertex(t)
		self.vertList[f].addNeighbor(self.vertList[t],cost)

	def getVertices(self):
		return self.vertList.keys()

	def __iter__(self):
		return iter(self.vertList.values())

# 实例化
g = Graph()
for i in range(6):
    g.addVertex(i)
# print(g.vertList)
g.addEdge(0,1,5)
g.addEdge(0,5,2)
g.addEdge(1,2,4)
g.addEdge(2,3,9)
g.addEdge(3,4,7)
g.addEdge(3,5,3)
g.addEdge(4,0,1)
g.addEdge(5,4,8)
g.addEdge(5,2,1)
for v in g:
    for w in v.getConnections():
        print("(%s , %s)"%(v.getId() , w.getId()))
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

弓早早o_O

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值