アルゴリズムベース-最短パスアルゴリズム


🌈 マルチアウトレットアルゴリズム(最短パス)


🔥 最短パスアルゴリズムとは?


🔥 優先順位キューを利用したマルチアウトプットアルゴリズムロジック


🔥 優先キューによる複数のアルゴリズムの実装


最短パスアルゴリズムとは?

  • 最短経路アルゴリズムの目的は、2つのノードを接続する最短経路を重み付け図において見つけ、幹線の重み付けと最小化を行うことである.
    したがって、
  • 最短パスアルゴリズムが重み付け図において最短パスを見つける問題は
  • である.

    1)最短パスアルゴリズムタイプ

  • 単点出発と単点到達(単源単運命最短経路問題)
  • 図のあるノードuから別のノードvへの最短経路の問題
  • を検索する.
  • 単点出発最短経路問題(単点源最短経路問題)
    グラフィック内の特定のノードuとグラフィック内の他のすべてのノードの最短パス問題(=マルチアウトプットアルゴリズム)
  • を検索する
  • フルペア最短パス
  • 図中のすべてのノード対(u,v)の最短経路問題
  • 2.優先順位キューを利用したマルチアウトプットアルゴリズムロジック

  • Aが特定のノードuであると指定する場合、マルチキャストアルゴリズムは、AとA-B、A-C、A-D、A-E、A-F、A-Dノードとの間の最短パス
  • を検索することを目標とする.
  • 、すなわち、より多くのノードを通っても虫歯の和の最小経路は最短経路
  • である.

    1)ステップ1:初期化

  • の第1の頂点宣言配列に基づいて、第1の頂点から各頂点までの距離
  • が記憶される.
  • 初期点の距離は0(A->A)であり、残りの点は無限大(INF)
  • として記憶する.
  • 優先キューには、まず最初の頂点(距離0)
  • を入れる.

    2)ステップ2:優先順位キューから抽出した(A,0)[ノード,1番目のノードからの距離]から隣接ノードからの距離を算出する

  • は、最初に第1の頂点のみを記憶するため、第1の頂点は
  • にポップアップされる.
  • の最初の頂点に隣接するノード(B、C、D...)野角では、1番目の頂点から各ノードまでの距離(図の値)と、現在の配列に格納されている1番目の頂点から各頂点までの距離(inf)
  • とを比較する.
  • のアレイに格納距離よりも、第1の頂点からノードまでの距離が短い場合、アレイはノードの距離
  • を更新する.
  • アレイにおいてノードからの距離が更新された場合、優先キュー
  • に入れる.
  • 優先キューは最小hip構造であるため、追加順序にかかわらず、最前面に最小値
  • を配置する.

    3)ステップ3:優先順位キュー(C,1)[ノード、1番目のノードとの距離]から隣接ノードとの距離を計算する

  • 優先キューの最小値はhipであり、上の表(C,1)、(D,2)、(B,8)の中(C,1)から
  • が最初に抽出(POP)される.
  • から第1段階までのA-B最短距離が8人の場合
  • .
  • A-Cまでの距離は1、C-Bは5であるため、A-Bから直接移動する8と比較して、A->C->Bの経路は6で最短経路を発見し、アレイ(優先順位キューに入れる)
  • に更新する.
  • から保存A-Dまでの距離は2、A->C->D経路は3であるため、Dの距離は
  • 更新されない.

    4)ステップ4:優先順位キュー(D,2)[ノード,1番目のノードからの距離]から隣接ノードの距離を計算する

  • infからEからFまでの距離
  • を計算した.
  • A->Dまでの距離2にD->Eを加えると3,E,5
  • となる.
    2から
  • A->Dまでの距離、D->Fは5、Fを加えると、7
  • 5)ステップ5:優先順位キュー(E,5)[ノード、最初のノードからの距離]に基づいて、この隣接ノードからの距離を計算する

  • A-Eの距離が5の場合、Eに隣接するFの距離は1である、すなわちA->E->Fは6であり、(F,7)
  • より小さい.
  • (F,7)が(F,6)
  • に更新された.

    6)ステップ6:優先順位キューから(B,6)(F,6)を順次抽出し、各ノードから隣接ノードとの距離を算出する

  • Bノードは他のノード
  • にルーティングする.
  • FノードにはAノードへの経路があるが、A-Aは0であるためより小さい、
  • を更新することができない.

    7)ステップ7:優先順位キューから順に抽出(F,7)(B,8)し、各ノードから隣接ノードとの距離を算出する

  • A-Fまでの距離は7であるが、すでにアレイ上のA-Fの最短距離であるため、より長い距離を計算する必要はなく、
  • をスキップする.

    8)ステップ8:A-Bまでのルート距離が8であるが、アレイ内のA-Bルートはすでに6であるため、距離を計算する必要がない


    3.マルチアウトレットアルゴリズムの実現


    1)heaqライブラリの利用

  • HEAQライブラリでは、データがリスト形式のときに0番のインデックスを優先順位として、
  • を低優先順位でポップアップできます.
    # heapq 라이브러리 활용하여 우선순위 큐 사용
    import heapq
    queue = []
    heapq.heappush(queue, [2, 'A'])
    heapq.heappush(queue, [5, 'B'])
    heapq.heappush(queue, [1, 'C'])
    heapq.heappush(queue, [7, 'C'])
    print(queue) # [[1, 'C'], [5, 'B'], [2, 'A'], [7, 'C']]
    for i in range(len(queue)):
        print(heapq.heappop(queue), end=' ') # [1, 'C'] [2, 'A'] [5, 'B'] [7, 'C'] 

    2)図形Python表現

    # 구현
    mygraph = {
        'A' : {'B':8, 'C':1, 'D':2},
        'B' : {},
        'C' : {'B':5, 'D':2},
        'D' : {'E':3, 'F':5},
        'E' : {'F':1},
        'F' : {'A':5}
    }

    3)複数曲線アルゴリズムの実現

    # 최단 경로 알고리즘
    # graph 구현
    mygraph = {
        'A': {'B': 8, 'C': 1, 'D': 2},
        'B': {},
        'C': {'B': 5, 'D': 2},
        'D': {'E': 3, 'F': 5},
        'E': {'F': 1},
        'F': {'A': 5}
    }
    # heapq 라이브러리 활용하여 우선순위 큐 사용
    # graph 구현
    graph = {
        'A': {'B':8, 'C':1, 'D':2},
        'B': {},
        'C': {'B':5, 'D':2},
        'D': {'E':3, 'F':5},
        'E': {'F':1},
        'F': {'A':5},
    }
    import heapq
    def dijkstra(graph, start):
        distances = {node : float('inf') for node in graph}
        distances[start] = 0 # {'A': 0, 'B': inf, 'C': inf, 'D': inf, 'E': inf, 'F': inf}
        queue = []
        heapq.heappush(queue, [distances[start], start]) # [[0, 'A']]
        while queue:
            current_distance, current_node = heapq.heappop(queue)
            # 이미 distnaces에 저장된 거리가 heap에서 꺼낸 누적된 거리보다 작다면 skip
            if distances[current_node] < current_distance:
                continue
            for adjacent, weight in graph[current_node].items():
                distance = current_distance + weight # 거리 = 현재까지의 거리 + 현재부터 해당 노드까지의 거리
                # 거리가 이미 distances에 저장된 거리보다 작다면 업데이트 후 queue에 추가
                if distance < distances[adjacent]:
                    distances[adjacent] = distance
                    heapq.heappush(queue, [distance, adjacent])
        return distances
    print(dijkstra(graph, 'A'))
    # {'A': 0, 'B': 6, 'C': 1, 'D': 2, 'E': 5, 'F': 6}
  • 幹線をEと呼ぶ場合,最短経路アルゴリズムの時間複雑度はO(E)+O(EGE)である.
    => O(ElogE)