1、实现有向图、无向图、有权图、无权图的邻接矩阵和邻接表表示方法
#有向图,连接表,有权值
class DirectedGraph(object):
def __init__(self,d):
self.__edges = {}
if isinstance(d,dict):
self.__graph = d
else:
self.__graph = dict()
raise KeyError("NO Input")
def add(self,f,e):
self.__graph[f].append(e)
print(self.__graph)
def delete(self,f,e):
self.__graph[f].remove(e)
print(self.__graph)
def __generatePath(self,graph,path,end,results):
#深度优先搜索 一条一条路径的找
curret = path[-1]
if curret == end:
results.append(path)
else:
for n in graph[curret]:
#找到从当前点出发指向的点
if n not in path:
self.__generatePath(graph,path+[n],end,results)
def searchPath(self,start,end):
self.__results = []
self.__generatePath(self.__graph,[start],end,self.__results)
self.__results.sort(key=lambda x:len(x))
#按所有路径的长度进行排序
print('The path from ',self.__results[0][0],'to',self.__results[0][-1],'is:')
for path in self.__results:
print(path)
def add_edge(self,front,back,value):
self.__edges[(front,back)]=value
def show(self):
print(self.__graph,'\n',self.__edges)
if __name__ == '__main__':
d={'A':['B','C','D'],
'B':['E'],
'C':['D','F'],
'D':['B','E','G'],
'E':['D'],
'F':['D','G'],
'G':['E']}
e = {
("A","B"):1,
("A","C"):2,
("A","D"):3,
("B","E"):4,
("C","D"):5,
("C","F"):6,
("D","B"):7,
("D","E"):8,
("D","G"):9,
("E","D"):10,
("F","D"):11,
("F","G"):12,
("G","E"):13
}
g=DirectedGraph(d)
for i in e.keys():
g.add_edge(i[0],i[1],e[i])
g.show()
# g.add_edge()
g.add('A','E')
g.delete("A","E")
g.searchPath('A','E')
'''result
The path from A to E is:
['A', 'B', 'E']
['A', 'D', 'E']
['A', 'C', 'D', 'E']
['A', 'D', 'B', 'E']
['A', 'D', 'G', 'E']
['A', 'C', 'D', 'B', 'E']
['A', 'C', 'D', 'G', 'E']
['A', 'C', 'F', 'D', 'E']
['A', 'C', 'F', 'G', 'E']
['A', 'C', 'F', 'D', 'B', 'E']
['A', 'C', 'F', 'D', 'G', 'E']
'''
2、实现图的深度优先搜索、广度优先搜索
def BFS(graph,s):
queue=[]
queue.append(s)
seen=set()#哈希set
seen.add(s)
parent={s:None}
#parent[w]=v 表示w的前一个点是v
while(len(queue)>0):
vertex=queue.pop(0)
nodes=graphs[vertex]
for w in nodes:
if w not in seen :
queue.append(w)
seen.add(w)
parent[w]=vertex
print(vertex)
return parent
def DFS(graph,s):
stack=[]
stack.append(s)
seen=set()#哈希set
seen.add(s)
while(len(stack)>0):
vertex=stack.pop()
nodes=graphs[vertex]
for w in nodes:
if w not in seen :
stack.append(w)
seen.add(w)
print(vertex)
3、实现 Dijkstra 算法、A* 算法
def dijkstra(graph,s):
pqueue=[]
heapq.heappush(pqueue,(0,s))
seen=set()#哈希set
#
parent={s:None}
distance=init_distance(graph,s)#距离起点的距离
#parent[w]=v 表示w的前一个点是v
while(len(pqueue)>0):
pair=heapq.heappop(pqueue)
dist=pair[0]
vertex=pair[1]
seen.add(vertex)
nodes=graph[vertex].keys()
for w in nodes:
if w not in seen :
if dist+graph[vertex][w]<distance[w]:
heapq.heappush(pqueue,(dist+graph[vertex][w],w))
parent[w]=vertex
distance[w]=dist+graph[vertex][w]
return parent,distance
A*算法还在研究
4、实现拓扑排序的 Kahn 算法、DFS 算法
def toposort(graph):
in_degrees = dict((u,0) for u in graph) #初始化所有顶点入度为0
vertex_num = len(in_degrees)
for u in graph:
for v in graph[u]:
in_degrees[v] += 1 #计算每个顶点的入度
Q = [u for u in in_degrees if in_degrees[u] == 0] # 筛选入度为0的顶点
Seq = [] # 排序的列表
while Q:
# 方法1
u = Q.pop() #默认从最后一个删除
# 方法2
# u = Q[0]
# Q = Q[1:]
Seq.append(u)
for v in graph[u]:
in_degrees[v] -= 1 #删除的节点连接的节点入度减一
if in_degrees[v] == 0:
Q.append(v) #再次筛选入度为0的顶点
if len(Seq) == vertex_num: #如果循环结束后存在非0入度的顶点说明图中有环,不存在拓扑排序
return Seq
else:
print("there's a circle.")
G = {
'a':'bc',
'b':'de',
'c':'f',
'd':'g',
'e':'' ,
'f':'',
'g':''
}
print(toposort(G))
#方法1 ['a', 'c', 'f', 'b', 'e', 'd', 'g']
#方法2 ['a', 'b', 'c', 'd', 'e', 'f', 'g']