python 實現dijkstra算法求解最短路徑

​ 重點:dijkstra算法按層計算其他點到源點的最短距離,層層擴展。node

1. dijkstra算法

  • 求解目標:找到圖中源點到其他點的最短距離,是單源點最短距離算法。
  • 總體思路:每一步都尋找到與源點最近的點,層層擴展,是貪心算法。
  • 具體實現:
    • 輸入:給定一個圖的鄰接表M,源點u。
    • 輔助變量:存儲與源點最短距離的字典、存儲已訪問節點的集合。
    • 算法過程:
      1. 初始化:將源點加入已訪問集合
      2. 對已訪問集合中每一個點的全部鄰接點,計算與源點的最短距離存入字典和已訪問集合。
      3. 重複2,直至全部頂點被訪問

2. 求解兩點最短路徑

​ 利用dijkstra算法,能夠找到圖中源點到其他點的最短距離。而求解兩點間最短路徑,只需找到兩點的最短距離和路徑。所以只須要在dijkstra算法中增添一個判斷語句便可獲得兩點間最短距離。python

def dijkstra(adjoin_map, u, v):
    '''給定一個圖的鄰接表M,兩點u和v,該代碼能返回兩點間的最短路徑和距離。
    :param adjoin_map: {node: [(node1, weight), (node2, weight2)]}
    :param u:
    :param v:
    :return: 損失
    '''
    if u == v:
        return 0
    cost_dct = {u: 0}  # 與源點的最短距離
    to_visited_set = {u}  # 須要訪問的集合
    find_status = False
    while not find_status:
        # 每次迭代擴展一層節點
        cur = to_visited_set.pop()
        for adjoin, cost in adjoin_map[cur]:
            # 計算最短距離
            cost_after = cost_dct[cur] + cost
            if adjoin in cost_dct.keys():
                if cost_after < cost_dct[adjoin]:  # 狀況1:若是已訪問且距離更短,則更新距離
                    cost_dct[adjoin] = cost_after
            else:  # 狀況2:未訪問,則加入
                cost_dct[adjoin] = cost_after
                to_visited_set.add(adjoin)
            if adjoin == v:  # 找到則跳出
                find_status = True
                break
    if v in cost_dct.keys():
        return cost_dct[v]
    return None

若須要保存最短路徑,則只須要增長一個字典,用來保存每一個節點的前驅節點。算法

相關文章
相關標籤/搜索