python 表示图论_python数据结构之图论

本篇学习笔记内容为图的各项性质、图的表示方法、图ADT的python实现

图(Graph)

是数据结构和算法学中最强大的框架之一(或许没有之一)。图几乎可以用来表现所有类型的结构或系统,从交通网络到通信网络,从下棋游戏到最优流程,从任务分配到人际交互网络,图都有广阔的用武之地。

我们会把图视为一种由“顶点”组成的抽象网络,网络中的各顶点可以通过“边”实现彼此的连接,表示两顶点有关联。我们要知道最基础最基本的2个概念,顶点(vertex)和边(edge)。

图可以分为有向图和无向图,一般用G=(V,E)来表示图。经常用邻接矩阵或者邻接表来描述一副图。

首先是链表、树与图的对比图:

圆为顶点、线为边

图的术语

图 G 是顶点V 和边 E的集合

两个顶点之间:边

如果顶点 x 和 y 共享边,则它们相邻,或者它们是相邻的

无向图 :无向图中的一个边可以在任一方向上遍历

路径::通过边连接的顶点序列

周期:第一个和最后一个顶点相同的路径

入度::顶点的度数V是以V为端点的边数

出度: 顶点的出度v是以v为起点的边的数量

度:顶点的度数是其入度和出度的总和

图的ADT

数据成员 :

顶点 (vertex)

边缘 (edge)

操作 :

有多少顶点?

有多少个边缘?

添加一个新的顶点

添加一个新的边缘

获取所有邻居? (进出)

U,V连接吗?

反转所有边缘?

获取2跳邻居

图表示法:邻接矩阵

classVertex:def __init__(self, node):

self.id=node#Mark all nodes unvisited

self.visited =FalsedefaddNeighbor(self, neighbor, G):

G.addEdge(self.id, neighbor)defgetConnections(self, G):returnG.adjMatrix[self.id]defgetVertexID(self):returnself.iddefsetVertexID(self, id):

self.id=iddefsetVisited(self):

self.visited=Truedef __str__(self):returnstr(self.id)classGraph:def __init__(self, numVertices=10, directed=False):

self.adjMatrix= [[None] * numVertices for _ inrange(numVertices)]

self.numVertices=numVertices

self.vertices=[]

self.directed=directedfor i inrange(0, numVertices):

newVertex=Vertex(i)

self.vertices.append(newVertex)def addVertex(self, vtx, id): #增加点,这个function没有扩展功能

if 0 <= vtx

self.vertices[vtx].setVertexID(id)defgetVertex(self, n):for vertxin inrange(0, self.numVertices):if n ==self.vertices[vertxin].getVertexID():returnvertxinreturnNonedef addEdge(self, frm, to, cost=0): #返回全部连线/航线

#print("from",frm, self.getVertex(frm))

#print("to",to, self.getVertex(to))

if self.getVertex(frm) is not None and self.getVertex(to) is notNone:

self.adjMatrix[self.getVertex(frm)][self.getVertex(to)]=costif notself.directed:#For directed graph do not add this

self.adjMatrix[self.getVertex(to)][self.getVertex(frm)] =costdefgetVertices(self):

vertices=[]for vertxin inrange(0, self.numVertices):

vertices.append(self.vertices[vertxin].getVertexID())returnverticesdefprintMatrix(self):for u inrange(0, self.numVertices):

row=[]for v inrange(0, self.numVertices):

row.append(str(self.adjMatrix[u][v])if self.adjMatrix[u][v] is not None else '/')print(row)defgetEdges(self):

edges=[]for v inrange(0, self.numVertices):for u inrange(0, self.numVertices):if self.adjMatrix[u][v] is notNone:

vid=self.vertices[v].getVertexID()

wid=self.vertices[u].getVertexID()

edges.append((vid, wid, self.adjMatrix[u][v]))returnedgesdefgetNeighbors(self, n):

neighbors=[]for vertxin inrange(0, self.numVertices):if n ==self.vertices[vertxin].getVertexID():for neighbor inrange(0, self.numVertices):if (self.adjMatrix[vertxin][neighbor] is notNone):

neighbors.append(self.vertices[neighbor].getVertexID())returnneighborsdefisConnected(self, u, v):

uidx=self.getVertex(u)

vidx=self.getVertex(v)return self.adjMatrix[uidx][vidx] is notNonedef get2Hops(self, u): #转一次机可以到达哪里

neighbors =self.getNeighbors(u)print(neighbors)

hopset=set()for v inneighbors:

hops=self.getNeighbors(v)

hopset|=set(hops)return list(hopset)

图表示法:邻接表

用邻接矩阵来表示,每一行表示一个节点与其他所有节点是否相连,但对于邻接表来说,一行只代表和他相连的节点:

可见邻接表在空间上是更省资源的。

邻接表适合表示稀疏图,邻接矩阵适合表示稠密图。

importsysclassVertex:def __init__(self, node):

self.id=node

self.adjacent={}#为所有节点设置距离无穷大

self.distance =sys.maxsize#标记未访问的所有节点

self.visited =False#Predecessor

self.previous =Nonedef addNeighbor(self, neighbor, weight=0):

self.adjacent[neighbor]=weight#returns a list

def getConnections(self): #neighbor keys

returnself.adjacent.keys()defgetVertexID(self):returnself.iddefgetWeight(self, neighbor):returnself.adjacent[neighbor]defsetDistance(self, dist):

self.distance=distdefgetDistance(self):returnself.distancedefsetPrevious(self, prev):

self.previous=prevdefsetVisited(self):

self.visited=Truedef __str__(self):return str(self.id) + 'adjacent:' + str([x.id for x inself.adjacent])def __lt__(self, other):return self.distance < other.distance and self.id

#value is Vertex

self.vertDictionary ={}

self.numVertices=0

self.directed=directeddef __iter__(self):returniter(self.vertDictionary.values())defisDirected(self):returnself.directeddefvectexCount(self):returnself.numVerticesdefaddVertex(self, node):

self.numVertices= self.numVertices + 1newVertex=Vertex(node)

self.vertDictionary[node]=newVertexreturnnewVertexdefgetVertex(self, n):if n inself.vertDictionary:returnself.vertDictionary[n]else:returnNonedef addEdge(self, frm, to, cost=0):if frm not inself.vertDictionary:

self.addVertex(frm)if to not inself.vertDictionary:

self.addVertex(to)

self.vertDictionary[frm].addNeighbor(self.vertDictionary[to], cost)if notself.directed:#For directed graph do not add this

self.vertDictionary[to].addNeighbor(self.vertDictionary[frm], cost)defgetVertices(self):returnself.vertDictionary.keys()defsetPrevious(self, current):

self.previous=currentdefgetPrevious(self, current):returnself.previousdefgetEdges(self):

edges=[]for key, currentVert inself.vertDictionary.items():for nbr incurrentVert.getConnections():

currentVertID=currentVert.getVertexID()

nbrID=nbr.getVertexID()

edges.append((currentVertID, nbrID, currentVert.getWeight(nbr)))#tuple

returnedgesdefgetNeighbors(self, v):

vertex=self.vertDictionary[v]return vertex.getConnections()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值