// 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); }