最短路径问题 Dijkstra ――Python实现

匿名 (未验证) 提交于 2019-12-02 22:51:30
 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!