1. 程式人生 > >最優路徑算法合集(附python源碼)(原創)

最優路徑算法合集(附python源碼)(原創)

最短 opened 假設 計算機科學 div 長度 特點 font aid

主要的最優(最短)路徑算法:

一、深度優先算法;二、廣度優先算法;三、Dijstra最短路徑;四、floyd最短路徑(待);

一、深度優先算法

  圖的深度優先搜索(Depth First Search),和樹的先序遍歷比較類似。

  它的思想:假設初始狀態是圖中所有頂點均未被訪問,則從某個頂點v出發,首先訪問該頂點,然後依次從它的各個未被訪問的鄰接點出發深度優先搜索遍歷圖,直至圖中所有和v有路徑相通的頂點都被訪問到。 若此時尚有其他頂點未被訪問到,則另選一個未被訪問的頂點作起始點,重復上述過程,直至圖中所有頂點都被訪問到為止。

  無向無權值網絡

技術分享圖片

data = [[0, 0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1, 0]]

技術分享圖片 技術分享圖片

技術分享圖片
 1 def depth_first_search(data, data_index):   # 有向、無向都可以滿足要求
 2     d1 = [data_index[0]]
 3     index_now = 0
 4 
 5     for i in range(len(data_index) - 1):  # 只需要再尋找剩余的數值即可
 6         state = 1
 7         for j in range(len(data[index_now])):  # 遍歷可行路徑
 8             if data[index_now][j] == 1:  #
如果該路徑可行,則直接判斷 9 if data_index[j] not in d1: # 判斷原始輸出中是否已有 10 d1.append(data_index[j])# 無,則加入 11 index_now = j 12 state = 0 13 break 14 if state: 15 for k in d1[-2::-1]: # 到達葉子後的操作
16 index_now = data_index.index(k) 17 for j in range(len(data[index_now])): # 遍歷可行路徑 18 if data[index_now][j] == 1: # 如果該路徑可行,則直接判斷 19 if data_index[j] not in d1: # 判斷原始輸出中是否已有 20 d1.append(data_index[j]) # 無,則加入 21 index_now = j 22 break 23 if index_now != data_index.index(k): 24 break 25 26 # print(d1) 27 return d1 28 29 if __name__ == "__main__": 30 data = [[0, 0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0], 31 [0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1, 0]] 32 data_w = [[0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 1, 0], [0, 0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0], 33 [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0]] 34 data_index = [A, B, C, D, E, F, G] 35 # print(data_index.index(‘F‘)) 36 d1 = depth_first_search(data_w, data_index) 37 print(d1)
View Code

輸入(無向圖):

data = [[0, 0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1, 0]]

輸出:

[‘A‘, ‘C‘, ‘B‘, ‘D‘, ‘F‘, ‘G‘, ‘E‘]

二、廣度優先算法

  

  廣度優先搜索算法(Breadth First Search),又稱為"寬度優先搜索"或"橫向優先搜索",簡稱BFS。

  它的思想是:從圖中某頂點v出發,在訪問了v之後依次訪問v的各個未曾訪問過的鄰接點,然後分別從這些鄰接點出發依次訪問它們的鄰接點,並使得“先被訪問的頂點的鄰接點先於後被訪問的頂點的鄰接點被訪問,直至圖中所有已被訪問的頂點的鄰接點都被訪問到。如果此時圖中尚有頂點未被訪問,則需要另選一個未曾被訪問過的頂點作為新的起始點,重復上述過程,直至圖中所有頂點都被訪問到為止。

  換句話說,廣度優先搜索遍歷圖的過程是以v為起點,由近至遠,依次訪問和v有路徑相通且路徑長度為1,2...的頂點。

技術分享圖片 技術分享圖片

技術分享圖片
 1 def breadth_first_search(data, data_index):  # 無向圖、有向圖都可以的
 2     d1 = [data_index[0]]
 3     index_now = [0]
 4     while len(d1) != len(data_index):
 5         index_mid = []
 6         for i in index_now:  # i 為當前 父節點
 7             for j in range(len(data[i])):  # 查詢父節點的子節點
 8                 if data[i][j] == 1:
 9                     if data_index[j] not in d1:
10                         d1.append(data_index[j])
11                         index_mid.append(j)
12         index_now = index_mid
13         print(d1)
14     return d1
15 
16 
17 if __name__ == "__main__":
18     data = [[0, 0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0],
19             [0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1, 0]]
20     data_w = [[0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 1, 0], [0, 0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0],
21               [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0]]
22     data_index = [A, B, C, D, E, F, G]
23     # print(data_index.index(‘F‘))
24     d1 = breadth_first_search(data_w, data_index)
25     # print(d1)
View Code

輸入(有向圖):

data_w = [[0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 1, 0], [0, 0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0]]

輸出:

[‘A‘, ‘B‘, ‘C‘, ‘E‘, ‘F‘, ‘D‘, ‘G‘]

三、Dijstra最短路徑(迪傑斯特拉算法)

參考視頻:https://www.bilibili.com/video/av25829980?from=search&seid=7854146334299589449

  迪傑斯特拉算法是由荷蘭計算機科學家狄克斯特拉於1959 年提出的,因此又叫狄克斯特拉算法。是從一個頂點到其余各頂點的最短路徑算法,解決的是有向圖中最短路徑問題。迪傑斯特拉算法主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。

  OSPF協議 :Open Shortest Path First開放式最短路徑優先,底層是迪傑斯特拉算法,是鏈路狀態路由選擇協議,它選擇路由的度量標準是帶寬,延遲。

技術分享圖片 技術分享圖片

技術分享圖片
 1 def priority_queue(data, d0):  # 自建優先隊列格式
 2     state = 1
 3     for i in range(len(data)):
 4         if d0[1] < data[i][1]:
 5             data.insert(i, d0)
 6             state = 0
 7             break
 8     if state:
 9         data.append(d0)
10     return data
11 
12 
13 def dijkstra_search(data, data_index, index):
14     parent = {}  # 字典映射,更新前級節點
15     queue = []  # 優先隊列
16     queue_out = [[data_index[index], data[index][index], 0]]  # 輸出隊列
17 
18     while len(queue_out) < len(data_index):
19         root_node = data_index.index(queue_out[-1][0])  # 當前最優節點
20         # print(root_node)
21         for i in range(len(data_index)):  # 遍歷所有的可能性
22             if data[root_node][i] != -1:  # 檢查是否可直連,是
23                 if data_index[i] not in [x[0] for x in queue_out]:
24                     queue = priority_queue(queue,
25                                            [data_index[i], data[root_node][i] + queue_out[-1][1], queue_out[-1][0]])
26         # print(queue)    # 檢查優先隊列的情況 [[‘C‘, 1], [‘B‘, 5]]
27 
28         for i in range(len(queue)):  # 0,1
29             # print(queue[i][0])
30             if queue[i][0] not in [x[0] for x in queue_out]:
31                 parent[queue[i][0]] = queue[i][-1]
32                 queue_out.append(queue[i])
33                 del queue[i]
34                 break
35 
36         # print(queue)
37         # print(‘queue_out‘,queue_out)
38     return queue_out, parent
39 
40 
41 if __name__ == "__main__":
42 
43     data_weight = [[0, 5, 1, -1, -1, -1], [5, 0, 2, 1, -1, -1], [1, 2, 0, 4, 8, -1], [-1, 1, 4, 0, 3, 6],
44                    [-1, -1, 8, 3, 0, -1], [-1, -1, -1, 6, -1, -1]]
45     data_index = [A, B, C, D, E, F]
46     # print(data_index.index(‘F‘))
47     d1, d2 = dijkstra_search(data_weight, data_index, 3)
48     print(d1)
49     print(d2)
50 
51     target = A
52     for i in d1:
53         if i[0] == target:
54             print(路徑最短距離為:, i[1])
55 
56     key = target
57     d3 = [target]
58     while key in d2.keys():
59         d3.insert(0, d2[key])
60         key = d2[key]
61     print(最優路線為:, d3)
View Code

輸入:

data_weight = [[0, 5, 1, -1, -1, -1], [5, 0, 2, 1, -1, -1], [1, 2, 0, 4, 8, -1], [-1, 1, 4, 0, 3, 6], [-1, -1, 8, 3, 0, -1], [-1, -1, -1, 6, -1, -1]]
data_index = [‘A‘, ‘B‘, ‘C‘, ‘D‘, ‘E‘, ‘F‘]
d1, d2 = dijkstra_search(data_weight, data_index, 0)

輸出:

路徑最短距離為: 10
最優路線為: [‘A‘, ‘C‘, ‘B‘, ‘D‘, ‘F‘]

四、floyd最短路徑

!!!還沒看這個算法!!!

最優路徑算法合集(附python源碼)(原創)