图论常识汇总:
所有顶点之间都有边的图称为完全图
n个顶点的无向图有n(n-1)/2条边,n个顶点的有向图有n(n-1)条边
一个顶点的度数表示他的边的个数
所有顶点的度数除以二分之一就是边数。如果是有向图,那么还分出度和入度。
有根图表示存在一个顶点 到其他所有定点都有路径。根顶点不一定只有一个。
连通表示两个顶点之间存在路径。
连通无向图:任意两个顶点之间连通就是连通无向图
强连通有向图:对于有向图,任意两个顶点都双向连通就表示强连通有向图
完全图都是连通图。
带权连通无向图称为网络。
图可以用邻接矩阵来表示,矩阵一般比较稀疏,节省空间可以用字典存储。
生成树:从任意顶点出发遍历图的所有顶点可以构成生成树。
权值最小的生成树称为最小生成树 MST
class Gragh:
def __init__(self,gragh):
self.graph = gragh[:]
self.point = ['A','B','C','D','E']
def show(self):
print(self.graph)
def Kruskal(self):
'''
Kruskal用于生成 最小生成树
在所有边中不停寻找最小边,直到所有顶点被连入连通分量
'''
graph = self.graph[:]
lst = sorted(graph,key=lambda x: x[-1])#先把所有的边按从小到大排序
d = {}
for i in self.point:
d[i] = -1
path = []
for loca in lst:
d[loca[0]] = d.get(loca[0]) + 1
d[loca[1]] = d.get(loca[1]) + 1
if not d[loca[0]] or not d[loca[1]]:#如果有一个不存在就加入路径
path.append(loca)
print(path)
return path
def Prim(self):
'''
Prim 算法同样用于生成最小生成树
随机确认一个初始顶点,查看其所有的边,找到最短的加到路径
重复上述步骤 直到包含所有的顶点'''
path = set()
l = ['B']#这里初始点可以随便改
graph = self.graph[:]
lst = sorted(graph, key=lambda x: x[-1]) # 先把所有的边按从小到大排序
while len(l)<5:#当所有顶点包含在内的时候就退出循环
ll = [x for x in lst if x[0] in l or x[1] in l]
for i in ll:
if i[0] not in l or i[1] not in l:
path.add(i)
tar = i[0] if i[0] not in l else i[1]
l.append(tar)
break
print(path)
return path
def Dijkstra(self,init_point):
'''Dijkstra 用于寻找最短路径,类似于动态规划
首先确认初始顶点,寻找下一个边界顶点,记录并更新最短的路径,直到所有顶点被遍历。'''
#初始化
graph = self.graph[:]
path = [[x] for x in graph if x[0] == init_point]
new_path = []#用于存放下一个边界的路径
d = {}
for i in path:
d[''.join([i[0][0],i[0][1]])] = i[0][-1],i
n = 0#用于记录是否还有节点
t = 0
#循环
print('initial path ==={} inital d{}'.format(path,d))
while True:
print('=====================================================')
for i in path:#对于每个路径i,查找他的下一个节点,形成新路径 [(ab3),(bc2)],[bc2]
point = i[-1][1]
l = [x for x in graph if x[0]== point]
print('当前路径{} 可供挑选的边界 :{}'.format(i,l))
for j in l:#对于所有可能的下一节点j
if j[1] in [f[0] for f in i]:#假如形成了环路就跳过,这一点非常重要,否则无限循环。
continue
else:
n+=1
tarl = i[:]
tarl.append(j)
new_path.append(tarl)
for i in new_path:
stri = ''.join([i[0][0],i[-1][1]])
distance = sum([j[-1] for j in i])
print(stri,i,distance)
if not d.get(stri,False):#假如是新路径,就添加路径
d[stri] = distance,i
if d.get(stri,False):#假如已经存在路径就查看是否更小
if distance