另外,还可以将图分为有权图和无权图,权表示两个节点之间的某种关系,比如交通运输网络中两个地点的权值可以代表交通费用,如图为有向图:
连通性:有时候,可能有两个区域的交通路线是没有相连的,这就会产生很多不连通的区域,如图就是不完全连通的:
邻接矩阵
如图为一个无向图,要用具体的数值表示节点之间的关系,可以使用邻接矩阵,假设这个矩阵是A, Aij A i j 就表示第i个节点和第j个节点是否相连,为1表示相连,0表示不相连。
除此之外,还可以使用邻接矩阵表示有向图:
邻接表
用邻接矩阵来表示,每一行表示一个节点与其他所有节点是否相连,但对于邻接表来说,一行只代表和他相连的节点:
可见邻接表在空间上是更省资源的。
邻接表适合表示稀疏图,邻接矩阵适合表示稠密图。
邻接矩阵
class DenseGraph:
def __init__(self,n,directed = False):
self.n = n # number of vertex
self.m = 0 #number of edge
self.directed = directed
self.matrix = [[0 for i in range(n)] for i in range(n)]
def __str__(self):
for line in self.matrix:
print(str(line))
return '' # must return string
def getNumberOfEdge(self):
return self.m
def getNumberOfVertex(self):
return self.n
def hasEdge(self,v,w):
if 0 <= v <= self.n and 0 <= w <= self.n:
return self.matrix[v][w]
else:
raise Exception("vertex not in the Graph")
def addEdge(self,v,w):
if 0 <= v <= self.n and 0 <= w <= self.n:
if self.hasEdge(v,w):
return
self.matrix[v][w]= 1
if self.directed is False:
self.matrix[w][v] = 1
self.m += 1
else:
raise Exception("vertex not in the Graph")
邻接表
lass Vertex(object):
def __init__(self,key):
self.id = key
self.connectedTo = {} #the key is vertex,value is weight
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 getConnectionsId(self):
idList = []
for k in self.connectedTo.keys():
idList.append(k.getId())
return sorted(idList)
def getConnectionsIdAndWeight(self):
idList = []
for k in self.connectedTo.keys():
idList.append(k.getId())
weightList = list(self.connectedTo.values())
return {idList[i]: weightList[i] for i in range(len(idList))}
def getWeight(self, nbr):
return self.connectedTo[nbr]
def getId(self):
return self.id
class SparseGraph(object):
def __init__(self,directed=False,weighted=False):
self.vertDict = {} #key is the id of vertex,value is vertex
self.numVertices = 0
self.directed=directed
self.weighted=weighted
def addVertex(self,key):
self.numVertices = self.numVertices + 1
newVertex = Vertex(key)
self.vertDict[key] = newVertex
return newVertex
def getVertex(self,n):
if n in self.vertDict:
return self.vertDict[n]
else:
return None
def __contains__(self,n):
return n in self.vertDict
def addEdge(self,f,t,weight=0):
if f not in self.vertDict:
self.addVertex(f)
if t not in self.vertDict:
self.addVertex(t)
self.vertDict[f].addNeighbor(self.vertDict[t], weight)
if self.directed is False:
self.vertDict[t].addNeighbor(self.vertDict[f], weight)
def getVertices(self):
return list(self.vertDict.keys())
def getVertNum(self):
return self.numVertices
def __iter__(self):
return iter(self.vertDict.values())
def getAllInfo(self):
verticesList=[int(x) for x in list(self.getVertices())]
verticesList.sort()
if self.weighted:
for i in range(len(verticesList)):
print('vertex %s : %s' % (i, self.getVertex(i).getConnectionsIdAndWeight()))
else:
for i in range(len(verticesList)):
print('vertex %s : %s' %(i,self.getVertex(i).getConnectionsId()))
打印出来看一下:
def buildGraphFromFile(aGraph,filePath):
graphList=[]
with open(filePath,'r',encoding='utf-8') as f:
for line in f:
graphList.append([int(x) for x in re.split(r'\s+',line.strip())])
for i in range(len(graphList)):
aGraph.addEdge(graphList[i][0],graphList[i][1])
# g1=DenseGraph(13) #必须填入正确的结点个数。。。我真的觉得邻接矩阵不好用
# buildGraphFromFile(g1,'/Users/huanghuaixian/desktop/testG1.txt')
# print(g1)
g2=SparseGraph()
buildGraphFromFile(g2,'/Users/huanghuaixian/desktop/testG2.txt')
g2.getAllInfo()