web-dev-qa-db-ja.com

ダイクストラアルゴリズムを使用して最短ルートを見つける

グラフの2つの頂点間の最短ルートを見つける必要があります。すべての重みを含む行列があります。どうすればいいですか?現在、私は次のコードを持っています:

private int[] Dijkstra(int start, int end)
    {
        bool[] done = new bool[8];
        int[] parent = new int[8];
        for (int i = 0; i < parent.Length; i++)
            parent[i] = -1;
        int[] distances = new int[8];
        for (int i = 0; i < distances.Length; i++)
            distances[i] = int.MaxValue;
        distances[start] = 0;
        int current = start;
        while (!done[current])
        {
            done[current] = true;
            for (int i = 0; i < 8; i++)
            {
                if (graph[current, i] != int.MaxValue)
                {
                    int dist = graph[current, i] + distances[current];
                    if (dist < distances[i])
                    {
                        distances[i] = dist;
                        parent[i] = current;
                    }
                }
            }
            int min = int.MaxValue;
            for (int i = 0; i < 8; i++)
            {
                if (distances[i] < min&&!done[i])
                {
                    current = i;
                    min = distances[i];
                }
            }
        }
        return parent;
    }

それは機能しますが、たとえば1と3の間の最短ルートを見つけて、1 => 4 => 2 => 3のようにルートを返す方法がわかりません。
前もって感謝します。

11
SirSergio

ダイクストラのアルゴリズムは、親配列を使用して、開始から終了までの最短パスを追跡します。 parent [end]から開始し、開始に戻るまで配列のエントリをたどります。

いくつかの擬似コード:

List<int> shortestPath = new List<int>();
int current = end;
while( current != start ) {
     shortestPath.Add( current );
     current = parent[current];
}

shortestPath.Reverse();

関数で心配する必要があるのは、渡された開始値と終了値が適切な値であるかどうかだけです(たとえば、グラフ内の頂点を実際に表しているかどうか)。

7
Travis

目的の頂点に到達したら、親行列を使用して開始頂点へのパスをバックトラックできます。次のようなもの(ソースから宛先へのパスがある場合):

void backtrack(int source, int dest, vector<int> &path) 
{
   path.Push_back(dest);

   for(int vertex = parent[dest]; vertex != source; vertex = parent[vertex])
     path.Push_back(vertex);

   path.Push_back(source);
}

注:パスは逆の順序になります。

3
Helstein