예제 #1
0
        // X - set of explored vertices of graph G
        // V-X - set of unexplored vertices of graph G
        //
        // Invariant.
        //     The key of a vertex w belongs to V-X is the min Dijkstra score of an edge with tail v belongs to X
        //     and head w, or +infinity if no such edge exists.
        //     key(w) = min len(v) + l(vw)
        //
        // DijkstraSearch(graph G, vertex s):
        //     // Initialization
        //     X = empty set
        //     H = empty min heap
        //     key(s) = 0
        //     for each vertex V in G.vertices do: key(V) = +infinity
        //     for each vertex V in G.vertices do: H.Insert(V)
        //     // Main loop
        //     while H is not empty do:
        //         w* = H.ExtractMin()
        //         X.Add(w*)
        //         len(w*) = key(w*)
        //         // Update Heap to maintain Invariant
        //         for every edge(w*, y) do:
        //             H.Delete(y)     // Delete: given a heap H and a pointer to an object y in H, delete y from H.
        //             key(y) = min {key(y), len(w*) + l(w*y)}
        //             H.Insert(y)
        public static int[] DijkstraMinHeap(IDirectedWeightedGraph <int> weightedGraph, int startVertex)
        {
            var minHeap          = new IndexMinHeap <int>(weightedGraph.VerticesCount);
            var exploredVertices = new HashSet <int> {
                startVertex
            };
            var len = new int[weightedGraph.VerticesCount + 1];

            for (int i = 1; i <= weightedGraph.VerticesCount; i++)
            {
                var score = i == startVertex ? 0 : 1000000;
                len[i] = score;
                minHeap.Insert(i, score);
            }

            while (!minHeap.IsEmpty())
            {
                int u = minHeap.GetMin();
                len[u] = minHeap.GetItemKey(u);
                minHeap.ExtractMin();
                exploredVertices.Add(u);

                foreach ((int v, int weight) in weightedGraph.GetAdjacentVertices(u))
                {
                    if (!exploredVertices.Contains(v))
                    {
                        if (len[v] > len[u] + weight)
                        {
                            int vKey     = minHeap.GetItemKey(v);
                            int newScore = Math.Min(len[u] + weight, vKey);
                            // can use (minHeap.Delete + minHeap.Insert) instead of DecreaseKey
                            // but this would be less effective
                            minHeap.DecreaseKey(v, newScore);
                            len[v] = newScore;
                        }
                    }
                }
            }

            return(len);
        }