利用dijkstra算法,来完成图中两个顶点间最短的距离,可以直接复制使用,只需要修改参数即可
1 def dijkstra_raw(edges, from_node, to_node):
2 """
3 将节点信息和边进行比较获取正确的边集
4 :param edges:
5 :param from_node:
6 :param to_node:
7 :return:正无穷大
8 """
9 g = defaultdict(list)
10 for l, r, c in edges:
11 g[l].append((c, r))
12 q, seen = [(0, from_node, ())], set()
13 while q:
14 (cost, v1, path) = heappop(q)
15 if v1 not in seen:
16 seen.add(v1)
17 path = (v1, path)
18 if v1 == to_node:
19 return cost, path
20 for c, v2 in g.get(v1, ()):
21 if v2 not in seen:
22 heappush(q, (cost + c, v2, path))
23 # inf 表示正无穷大
24 return float("inf"), []
25
26
27 def dijkstra(edges, from_node, to_node):
28 """
29 gain the shortest path and this node information
30 :param edges: this is a array of path
31 :param from_node: start node
32 :param to_node: end node
33 :return: the shortest path and this node information
34 """
35 len_shortest_path = -1
36 ret_path = []
37 length, path_queue = dijkstra_raw(edges, from_node, to_node)
38 if len(path_queue) > 0:
39 # 1. Get the length firstly;
40 len_shortest_path = length
41 # 2. Decompose the path_queue, to get the passing nodes in the shortest path.
42 left = path_queue[0]
43 # 2.1 Record the destination node firstly;
44 ret_path.append(left)
45 right = path_queue[1]
46 while len(right) > 0:
47 left = right[0]
48 # 2.2 Record other nodes, till the source-node.
49 ret_path.append(left)
50 right = right[1]
51 # 3. Reverse the list finally, to make it be normal sequence.
52 ret_path.reverse()
53 return len_shortest_path, ret_path
54
55
56 def get_shortest_path(start_node, end_node):
57 """
58 the shortest_path of matrix
59 :param start_node: start_position
60 :param end_node: end_position
61 :return: the shortest_path
62 """
63 # endless是不存在边的界限
64 endless = 0
65 edges_list = []
66 m_top = get_array(0)
67 for i in range(len(m_top)):
68 for j in range(len(m_top[0])):
69 if i != j and m_top[i][j] != endless:
70 edges_list.append((i, j, m_top[i][j])) # (i,j) is a link; m_top[i][j] here is 1, the length of link (i,j).
71 return dijkstra(edges_list, start_node, end_node)