1. 程式人生 > >數學建模 of python(最短路問題)

數學建模 of python(最短路問題)

吉吉:

Dijkstra_Animation.gif - 無向圖,正權值路徑

  • 頂點為城市,頂點間連線表示城市相連通,線上數字為城市間距離。

     

    城市間距離

  • 目標為找出從序號為1的城市到序號為5的城市的最短路徑。

  • 該路徑可以由 已知最短路徑 迭代求出。

  • 每次從已知最短路徑中選出沒探索過最短的,從該路徑終點出發,探索新的最短路徑。

  • 一開始,從出發點到達它之外的所有頂點的已知最短路徑為無窮大,到出發點自己的最短路徑為0。

  • 現在,出發點的已知最短路徑最小,則從出發點出發,探索與其直連的所有頂點,如果路徑長度比到該頂點的已知最短路徑小,則重新整理該頂點的已知最短路徑

  • 接著,出發點已經探索過了,從未出發探索過的已知最短路徑中選出最小的一個,即從城市2出發,探索與其直連的城市,如果到達該城市的路徑長度比已知最短路徑小,則重新整理最短路徑。可以看到,從城市2到3的路徑總長17>城市3目前的最短路徑9,不滿足條件,不重新整理城市3的最短路徑,而到城市4的已知最短路徑重新整理為7+15=21。(已知最短路徑的計算都是從出發點開始)

  • 依次類推,直到我們遇到目的地是已知最短路徑裡未探索的所有頂點中最短的一個時,終止探索。

  • 值得注意的是,我們每一步探索過程中的當前出發點的最短路徑是確定的了不會再變了,因為它是所有未探索過的已知最短路徑中的最小的了,所以不存在從其它地方再加一段路程到達它

    還會比它更小的情況。

程式碼(這裡用到python的堆結構):

from heapq import heappop, heappush 
V = [ # 頂點列表 
     1, 2, 3, 4, 5, 6] 
w = [ # 城市間距離, -1表示無窮大 
     [ 0, 7, 9, -1, -1, 14],
     [ 7, 0, 10, 15, -1, -1],
     [ 9, 10, 0, 11, -1, 2],
     [-1, 15, 11, 0, 6, -1], 
     [-1, -1, -1, 6, 0, 9],
     [14, -1, 2, -1, 9, 0]] 
def Dijkstra(V=V, w=w, s=1, dest=5):
    N = len(V) # 頂點數 
    S = set() 
    Q = [(0, V.index(s), str(s))] # 路徑長, 序號, 路徑 
    v_d = V.index(dest) 
    while Q : # 當Q非空 
        d, u, p = heappop(Q) 
        if u == v_d : 
            print(d, p) 
            break # 可以在找到目的地之後立即終止,也可繼續查詢完所有最短路徑 
            # 如果到目的地的距離已經是當前所有距離中最短的,那不可能會有更短的,所以退出 
        if u not in S: 
            S.add(u) 
            v_reached_from_u = [i for i in range(N) if w[u][i] != -1] # u能到達的頂點 
            for v in v_reached_from_u: 
                if v not in S: 
                    heappush(Q,( (d + w[u][v]), v, ''.join((p,'->',str(V[v]))) )) # 到頂點v的某條路徑的距離 
Dijkstra() # 20 1->3->6->5