python解決最短路徑問題:Floyd-Warshall演算法
阿新 • • 發佈:2019-02-03
昨晚做的華為實習生筆試題第三題的解答就涉及到最短路徑問題,今天查閱資料l,重新做了一下。
主要思路:
1.根據天氣狀況更新路線圖hmap
2.根據最新的路線圖hmap,運用最短路徑演算法Floyd-Warshall演算法,求得任意兩城市之間最短路徑所必須經過的城市,放在path矩陣中(A矩陣存放對應的權值)
3.然後編寫一個函式getRoutes(path,start,end),根據指定的起始點和終點獲得路徑。
程式碼:
執行結果:#coding= utf-8 #最短路徑問題:能到X的所有城市(除去自身),找到時間最小對應的城市M,然後找5到M的時間最小對應的城市,不斷遞推 #大霧城市:不可從該城市出發,也不可到達該城市,對應行列時間為1000 #從城市5出發到達任意城市的最短時間對應的路徑,及 #根據大霧城市設定新的map,y中存放的為大霧城市列表 from collections import defaultdict from heapq import * ''' def dijkstra_raw(edges, from_node, to_node): g = defaultdict(list) for l,r,c in edges: g[l].append((c,r)) q, seen = [(0,from_node,())], set() while q: (cost,v1,path) = heappop(q) if v1 not in seen: seen.add(v1) path = (v1, path) if v1 == to_node: return cost,path for c, v2 in g.get(v1, ()): if v2 not in seen: heappush(q, (cost+c, v2, path)) return float("inf"),[] def dijkstra(edges, from_node, to_node): len_shortest_path = -1 ret_path=[] length,path_queue = dijkstra_raw(edges, from_node, to_node) if len(path_queue)>0: len_shortest_path = length ## 1. Get the length firstly; ## 2. Decompose the path_queue, to get the passing nodes in the shortest path. left = path_queue[0] ret_path.append(left) ## 2.1 Record the destination node firstly; right = path_queue[1] while len(right)>0: left = right[0] ret_path.append(left) ## 2.2 Record other nodes, till the source-node. right = right[1] ret_path.reverse() ## 3. Reverse the list finally, to make it be normal sequence. return len_shortest_path,ret_path ''' def setNewMap(y): t = [[0,2,10,5,3,1000], [1000,0,12,1000,1000,10], [1000,1000,0,1000,7,1000], [2,1000,1000,0,2,1000], [4,1000,1000,1,0,1000], [3,1000,1,1000,2,0]] if len(y) == 1 and y[0] == '0': return t #字串變為int for i in xrange(len(y)): y[i] = int(y[i]) #對應城市的行變為1000 for i in xrange(len(y)): t[y[i]-1] = [1000,1000,1000,1000,1000,1000] #對應城市的列變為1000 for i in xrange(6): for j in y: t[i][j-1] = 1000 return t #根據最短路徑矩陣,輸出兩點之間對應的路線 def getRoutes(path,start,end): #最短路徑矩陣 rts = [] #存放路線 rts.append(start) i = start-1 while path[i][end-1] != -1: rts.append(path[i][end-1]+1) i = path[i][end-1] rts.append(end) return rts #求最短路徑:指定起點sn,終點en和地圖tmp def shortestPath(tmp): A = tmp path= [] #存放到某點必須經過的路徑點 for i in xrange(6): path.append([-1,-1,-1,-1,-1,-1]) for k in xrange(6): for i in xrange(6): for j in xrange(6): if A[i][j] > A[i][k] + A[k][j]: A[i][j] = A[i][k] + A[k][j] path[i][j] = k print 'A:%s'%(A) print 'path:%s'%(path) return A,path hmap = [[0,2,10,5,3,1000], [1000,0,12,1000,1000,10], [1000,1000,0,1000,7,1000], [2,1000,1000,0,2,1000], [4,1000,1000,1,0,1000], [3,1000,1,1000,2,0]] ''' lines = [] #存放最短路徑 #目的城市 X = raw_input() #大霧城市,多個大霧城市時以,分割 Y = [] while True: ins = raw_input() if not ins: break Y = ins.split(',') #更新當前路徑地圖 tmp = setNewMap(Y) ''' Y = [4] tmp = setNewMap(Y) a,path = shortestPath(tmp) rts = getRoutes(path,5,2) print rts
這一個測試用例通過了。
總結:
分析問題,剖析出對應的演算法,稍加改造執行實現。
最短路徑演算法參考連結: