图的概念及相关术语
概念
painting:用画刷画的油画
drawing:用硬笔画的素描/线条画
picture:真实形象所反映的画,如照片等,如take picture
image:由印象而来的画,遥感影像做image,因是经过传感器印象而来
figure:轮廓图的意思,某个侧面的轮廓,所以有figure out的说法
diagram:抽象的概念关系图,如电路图、海洋环流图、类层次图
chart:由数字统计来的柱状图、饼图、折线图
map:地图
plot:地图上的一小块
graph:重在由一些基本元素构造而来的图,如点、线段等
图Graph是比树更为一般的结构,也是由节点和边构成。实际上树是一种具有特殊性质的图,图可以用来表示现实世界中很多事物
术语介绍
顶点Vertex: (也称“节点Node”是图的基本组成部分,顶点具有名称标识Key,也可以携带数据项payload
边Edge: (也称"弧Arc"作为2个顶点之间关系的表示,边连接两个顶点;边可以是无向或者有向的,相应的图称作“无向图”和“有向图”
权重Weight: 为了表达从一个顶点到另一个顶点的“代价”,可以给边赋权;例如公交网络中两个站点之间的“距离”’、“通行时间”和“票价”都可以作为权重。
定义
图在数学中的定义可以是G=(V, E),其中V是顶点的集合,E是边的集合,E中的每条边e=(v, w),v和w都是V中的顶点;如果是赋权图,则可以在e中添加权重分量子图:V和E的子集
有向赋权图,权重为整数
路径Path: 图中的路径,是由边依次连接起来的顶点序列;无权路径的长度为边的数量;带权路径的长度为所有边权重的和
圈Cycle: 圈是首尾顶点相同的路径,如果有向图中不存在任何圈,则称作“有向无圈图directed acyclic graph: DAG”
图的操作
Graph():创建一个空的图;
addVertex(vert):将顶点vert加入图中
addEdge(fromVert, toVert):添加有向边
addEdge ( fromVert,toVert, weight):添加带权的有向边
getVertex(vKey):查找名称为vKey的顶点
getVertices():返回图中所有顶点列表
in:按照vert in graph的语句形式, 返回顶点是否存在图中True/False
图的实现
ADT Graph的实现方法有两种主要形式:邻接矩阵adjacency matrix、邻接表adjacency list
两种方法各有优劣,需要在不同应用中加以选择
邻接矩阵
矩阵的每行和每列都代表图中的顶点。如果两个顶点之间有边相连,设定行列值
无权边则将矩阵分量标注为1,或者0;带权边则将权重保存为矩阵分量值
邻接矩阵实现法的优点是简单,可以很容易得到顶点是,如何相连,但如果图中的边数很少则效率低下,成为“稀疏sparse”矩阵,而大多数问题所对应的图都是稀疏的,边远远少于这个量级
邻接列表
邻接列表adjacency list可以成为稀疏图的更高效实现方案。维护一个包含所有顶点的主列表(master list),主列表中的每个顶点,再关联一个与自身有边连接的所有顶点的列表
邻接列表法的存储空间紧凑高效,很容易获得顶点所连接的所有顶点,以及连接边的信息
编程实现
Vertex包含了顶点信息,以及顶点连接边信息
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]
Graph保存了包含所有顶点的主表
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): # 通过key查找顶点
if n in self.vertList:
return self.vertList[n]
else:
return None
def __contains__(self, n):
return n in self.vertList
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())