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

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

1、深度優先算法;2、廣度優先算法;3、Dijstra最短路徑;4、floyd最短路徑(待);算法

 

1、深度優先算法網絡

 

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

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

 

  無向無權值網絡spa

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

 輸入(無向圖):3d

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]]

輸出:code

['A', 'C', 'B', 'D', 'F', 'G', 'E']視頻

 

2、廣度優先算法blog

  

  廣度優先搜索算法(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']

 

3、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']

 

4、floyd最短路徑

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

相關文章
相關標籤/搜索