最短路徑算法的實現(dijskstra):Python


dijskstra最短路徑算法步驟:

輸入:圖G=(V(G),E(G))有一個源頂點S和一個匯頂點t,以及對所有的邊ij屬於E(G)的非負邊長出cij。

輸出:G從s到t的最短路徑的長度。

第0步:從對每個頂點做臨時標記L開始,做法如下:L(s)=0,且對除s外所有的頂點L(i)=∞。

第1步:找帶有最小臨時標記的頂點(如果有結,隨機地取一個),使得該標記變成永久標記,意該標記永久不再改變。

第2步:對沒有永久標記但是又與帶永久標記的頂點相鄰的頂點j,按如下方法計算一個新的臨時標記:L(j)=min(L(i)+cij),求最小是對所有帶永久標記的頂點i做的,重復1和2,知道所有的頂點都打上永久標記。

時間復雜度:O(n^2)

 

python代碼如下

 1 __author__='wym'
 2 #coding=cp936
 3 class Algorithm():
 4     point_list=[]
 5     edge_list=[]
 6     def dijkstra(self,start_point,point_list,edge_list):
 7         '''
 8         @point為起始點
 9         @point_list為頂點列表
10         @edge_list為邊列表
11         '''       
12         #列表點
13         temp_point=[]
14         #起始點,在列表點中的位置
15         point_index=point_list.index(start_point)
16         #初始點到其余各點的距離字典
17         dis_dic=dict()
18         #邊列表的首端點列表
19         temp_edge=[]
20         #距離初始化
21         dis_list=['inf']*len(point_list)
22         temp_point.append(start_point)
23         dis_list[point_index]=0
24         for i in range(len(point_list)):
25             dis_dic.setdefault(point_list[i],dis_list[i])
26         for i in range(len(edge_list)):
27             temp_edge.append(edge_list[i][0])
28         point=start_point
29         #依次遍歷加入最小距離的點,並更新原列表中點的距離
30         while len(temp_point)<len(point_list):
31             index=self.find_index(point,temp_edge,edge_list,temp_point)
32             #判斷是否走的通
33             if len(index)>0:
34                 value=edge_list[index[0]][2]
35                 add_index=index[0]
36                 for i in index:
37                     if edge_list[i][0] in dis_dic:
38                         dis_dic[edge_list[i][1]]=min(float(edge_list[i][2])+float(dis_dic[point]),float(dis_dic[edge_list[i][1]]))
39                     if value>edge_list[i][2]:
40                         value=edge_list[i][2]
41                         add_index=i
42                 temp_point.append(edge_list[add_index][1])
43                 point=edge_list[add_index][1]
44             else:
45                 point=in_list[in_list.index(point)-1]
46         print dis_dic
47         return dis_dic
48     def find_index(self,point,temp_edge,edge_list,temp_point):
49         '''
50         @point:遍歷點基准點
51         @temp_edge:邊列表的首端點列表
52         @edge_list:邊權列表
53         @temp_point:列表點
54         @返回邊權列表列表索引
55         '''
56         #尋找點的索引,並去除已在列表中的點
57         index=[]
58         for i in range(len(temp_edge)):
59             if point==temp_edge[i] and edge_list[i][1] not in temp_point:
60                 index.append(i)
61         return index
62         
63 if __name__=="__main__":
64     print '請輸入無向圖的頂點'
65     point_list=input()
66     print '請輸入無向圖的邊'
67     edge_list=list(input())
68     print '請輸入各邊長度'
69     for i in range(len(edge_list)):
70         print '頂點'+str(edge_list[i][0])+'頂點'+str(edge_list[i][1])+'的長度為:'
71         length=[input("長度為:")]
72         edge_list[i]+=length
73         edge_list.append([edge_list[i][1],edge_list[i][0],length[0]])
74     while True:
75         print '請輸入起始點'
76         start_point=input("start_point=")
77         if start_point in point_list:
78             obj=Algorithm()
79             obj.dijkstra(start_point,point_list,edge_list)
80             break
81         else:
82             print '該點不在圖中,請重新輸入:'
83             continue

 

運行結果:

請輸入無向圖的頂點
1,2,3,4,5,6
請輸入無向圖的邊
[1,6],[1,3],[1,2],[2,3],[3,6],[2,4],[3,4],[4,5],[5,6]
請輸入各邊長度
頂點1頂點6的長度為:
長度為:14
頂點1頂點3的長度為:
長度為:9
頂點1頂點2的長度為:
長度為:7
頂點2頂點3的長度為:
長度為:10
頂點3頂點6的長度為:
長度為:2
頂點2頂點4的長度為:
長度為:15
頂點3頂點4的長度為:
長度為:11
頂點4頂點5的長度為:
長度為:6
頂點5頂點6的長度為:
長度為:9
請輸入起始點
start_point=1
{1: 0, 2: 7.0, 3: 9.0, 4: 20.0, 5: 20.0, 6: 11.0}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM