主要的最优(最短)路径算法: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)
输入(无向图):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)
输入(有向图):
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)
输入:
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最短路径
!!!还没看这个算法!!!