# 最短路径算法 Dijkstra
# 输入:含权有向图 G=(V,E),V={1,2,3...n}
# 输出:G中顶点 1 到各个顶点地最短距离
1 class Vertex:
2 #顶点类
3 def __init__(self,vid,outList):
4 self.vid = vid #出边
5 self.outList = outList #出边指向的顶点id的列表,也可以理解为邻接表
6 self.know = False #默认为假
7 self.dist = float('inf') #s到该点的距离,默认为无穷大
8 self.prev = 0 #上一个顶点的id,默认为0
9 def __eq__(self, other):
10 if isinstance(other, self.__class__):
11 return self.vid == other.vid
12 else:
13 return False
14 def __hash__(self):
15 return hash(self.vid)
1 #创建顶点对象 2 v1=Vertex(1,[2,3]) 3 v2=Vertex(2,[3,4]) 4 v3=Vertex(3,[5]) 5 v4=Vertex(4,[3,5,6]) 6 v5=Vertex(5,[6]) 7 v6=Vertex(6,[]) 8 9 #存储边的权值 10 edges = dict() 11 def add_edge(front,back,value): 12 edges[(front,back)]=value 13 add_edge(1,2,1) 14 add_edge(1,3,12) 15 add_edge(2,3,9) 16 add_edge(2,4,3) 17 add_edge(3,5,5) 18 add_edge(4,3,4) 19 add_edge(4,5,13) 20 add_edge(4,6,15) 21 add_edge(5,6,4)
1 #创建一个长度为7的数组,来存储顶点,0索引元素不存 2 vlist = [False,v1,v2,v3,v4,v5,v6] 3 #使用set代替优先队列,选择set主要是因为set有方便的remove方法 4 vset = set([v1,v2,v3,v4,v5,v6])
1 def get_unknown_min():#此函数则代替优先队列的出队操作 2 the_min = 0 3 the_index = 0 4 j = 0 5 for i in range(1,len(vlist)): 6 if(vlist[i].know is True): 7 continue 8 else: 9 if(j==0): 10 the_min = vlist[i].dist 11 the_index = i 12 else: 13 if(vlist[i].dist < the_min): 14 the_min = vlist[i].dist 15 the_index = i 16 j += 1 17 #此时已经找到了未知的最小的元素是谁 18 vset.remove(vlist[the_index])#相当于执行出队操作 19 return vlist[the_index]
1 def main():
2 #将v1设为顶点
3 v1.dist = 0
4
5 while(len(vset)!=0):
6 v = get_unknown_min()
7 print(v.vid,v.dist,v.outList)
8 v.know = True
9 for w in v.outList:#w为索引
10 if(vlist[w].know is True):
11 continue
12 if(vlist[w].dist == float('inf')):
13 vlist[w].dist = v.dist + edges[(v.vid,w)]
14 vlist[w].prev = v.vid
15 else:
16 if((v.dist + edges[(v.vid,w)])<vlist[w].dist):
17 vlist[w].dist = v.dist + edges[(v.vid,w)]
18 vlist[w].prev = v.vid
19 else:#原路径长更小,没有必要更新
20 pass
函数调用:
1 main()
2 print('v.dist 即为从起始点到该点的最短路径长度:')
3 print('v1.prev:',v1.prev,'v1.dist',v1.dist)
4 print('v2.prev:',v2.prev,'v2.dist',v2.dist)
5 print('v3.prev:',v3.prev,'v3.dist',v3.dist)
6 print('v4.prev:',v4.prev,'v4.dist',v4.dist)
7 print('v5.prev:',v5.prev,'v5.dist',v5.dist)
8 print('v6.prev:',v6.prev,'v6.dist',v6.dist)
运行结果:
1 0 [2, 3] 2 1 [3, 4] 4 4 [3, 5, 6] 3 8 [5] 5 13 [6] 6 17 [] v.dist 即为从起始点到该点的最短路径长度: v1.prev: 0 v1.dist 0 v2.prev: 1 v2.dist 1 v3.prev: 4 v3.dist 8 v4.prev: 2 v4.dist 4 v5.prev: 3 v5.dist 13 v6.prev: 5 v6.dist 17
