利用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)