Pythonで幅優先グラフ探索アルゴリズムを使って完全連結グラフの最短ノードを求める方法

スポンサーリンク

グラフのトラバーサルアルゴリズムは様々な応用が可能です。

その応用の一つに、グラフの2つのノード間の最小距離を求めることがある。

今回は、重みのない完全連結グラフにおいて、幅優先グラフ探索アルゴリズムを用いて最小距離を求めるアルゴリズムをpythonで実装します。

スポンサーリンク

BFSアルゴリズムをGRaphに使う

Breadth-first search はグラフの探索アルゴリズムの一つで、グラフの各頂点を任意の1点から正確に1回だけ探索します。

選択された各頂点について、まずその頂点を表示し、次にその近傍点をすべて表示します。

この処理は、すべての頂点を走査し終えるまで続けられる。

幅優先探索でグラフを走査している間は、選択した頂点から何層にも移動しているように見えます。

グラフに対するBFSアルゴリズムの実装は次の通りです。

このアルゴリズムでは、グラフは無重量、無向性、完全連結であると仮定しています。

def bfs(graph, source):
    Q = Queue()
    visited_vertices = set()
    Q.put(source)
    visited_vertices.update({0})
    while not Q.empty():
        vertex = Q.get()
        print(vertex, end="-->")
        for u in graph[vertex]:
            if u not in visited_vertices:
                Q.put(u)
                visited_vertices.update({u})

重みのないグラフの2つのノード間の最短距離の決定

幅優先探索アルゴリズムにある種の修正を加えることで、あるソースからすべてのノードへの最短距離を求めることができる。

グラフのソースと隣接リスト表現が与えられたら、訪問したすべての頂点を含むリストを宣言し、さらに、辞書のキーが頂点を決定し、値が現在の頂点とソースの間の距離を決定する辞書を作成します。

BFSアルゴリズムの変更点は、頂点vを処理するたびに、その近傍の距離を更新することです。

vの近傍の送信元からの距離は、vの送信元からの距離を1つ足したものとなる。

最小距離を求めるアルゴリズム

発生源から各頂点までの最短距離の求め方は大体分かったので、そのアルゴリズムを定式化します。

Algorithm Least Distance:
Input: Graph(Adjacency list) and Source vertex
Output: A list with distance of each vertex from source
Start:
    1.Create an empty queue Q.
    2.Create an empty set to keep record of visited vertices.
    3. Create a dictionary in which keys of the dictionary determine the vertex and values determine the distance between current vertex and source.
    4.Insert source vertex into the Q and Mark the source as visited.
    5.If Q is empty, return. Else goto 6.
    6.Take out a vertex v from Q.
    7.Insert all the vertices in the adjacency list of v which are not in the visited list into Q and mark them visited after updating their distance from source.
    8.Goto 5.
Stop.

最小距離を計算するグラフのトラバーサルを実装する

ソースからの頂点の最小距離を求めるアルゴリズムを定式化したので、そのアルゴリズムを実装し、次の画像で与えられるグラフに対してアルゴリズムを実行します。

from queue import Queue
 
myGraph = {0: [1, 3], 1: [0, 2, 3], 2: [4, 1, 5], 3: [4, 0, 1], 4: [2, 3, 5], 5: [4, 2]}
 
 
def leastDistance(graph, source):
    Q = Queue()
    # create a dictionary with large distance(infinity) of each vertex from source
    distance = {k: 9999999 for k in myGraph.keys()}
    visited_vertices = set()
    Q.put(source)
    visited_vertices.update({0})
    while not Q.empty():
        vertex = Q.get()
        if vertex == source:
            distance[vertex] = 0
        for u in graph[vertex]:
            if u not in visited_vertices:
                # update the distance
                if distance[u] > distance[vertex] + 1:
                    distance[u] = distance[vertex] + 1
                Q.put(u)
                visited_vertices.update({u})
    return distance
 
 
print("Least distance of vertices from vertex 0 is:")
print(leastDistance(myGraph, 0))

Pythonによるアルゴリズムの実装は以下の通りです。

Least distance of vertices from vertex 0 is:
{0: 0, 1: 1, 2: 2, 3: 1, 4: 2, 5: 3}

結果を出力すると、以下の様になります。

Graph Implementation In Python
Graph Implementation In Python- Askpython

まとめ

今回は、深さ優先探索のトラバーサルアルゴリズムを用いて、グラフのソースと他の頂点との間の最小距離を求めるアルゴリズムを実装しました。

今後も有益な記事を期待しています。

タイトルとURLをコピーしました