public Dijkstra(WeightSpareGraph <float> graph, int src) { Debug.Assert(src >= 0 && src < graph.V()); this.src = src; this.graph = graph; this.n = graph.V(); this.m = graph.E(); shortPath = new float[n]; book = new bool[n]; from = new int[n]; for (int i = 0; i != n; i++) { book [i] = false; from [i] = -1; //假设都是可达的 } from [src] = -1; shortPath [src] = 0f; IndexMinHeap <float> indexMinHeap = new IndexMinHeap <float> (n); indexMinHeap.Insert(src, shortPath[src]); while (indexMinHeap.Size() != 0) { int u = indexMinHeap.ExtraMinItemIndex(); book [u] = true; WeightSpareGraph <float> .adjIterator iter = new WeightSpareGraph <float> .adjIterator(graph, u); for (Edge <float> e = iter.begin(); !iter.isEnd(); e = iter.Next()) { int v = e.Other(u); if (!book[v]) { if (from [v] == -1 || shortPath [v] > shortPath [u] + e.weight) { from [v] = u; shortPath [v] = shortPath [u] + e.weight; if (indexMinHeap.isContain(v)) { indexMinHeap.Change(v, shortPath [v]); } else { indexMinHeap.Insert(v, shortPath[v]); } } } } } }
public void visit(int u) { WeightSpareGraph <float> .adjIterator iter = new WeightSpareGraph <float> .adjIterator(graph, u); for (Edge <float> e = iter.begin(); !iter.isEnd(); e = iter.Next()) { if (book [e.Other(u)]) { continue; } int v = e.Other(u); // u if (toEdgeArr [v] == null) { toEdgeArr [v] = e; indexMinHeap.Insert(v, e.weight); } else { if (toEdgeArr [v].CompareTo(e) > 0) { toEdgeArr [v] = e; indexMinHeap.Change(v, e.weight); } } } }
// 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); }
private void Visit(int v) { if (!marked[v]) { marked[v] = true; foreach (Edge <TWeight> e in G.GetAdjIterator(v)) { var w = e.Other(v); if (!marked[w]) { if (EdgeTo[w] == null) { ipq.Insert(w, e.Weight); EdgeTo[w] = e; } else if (e.Weight.CompareTo(EdgeTo[w].Weight) < 0) { EdgeTo[w] = e; ipq.Change(w, e.Weight); } } } } }
// Use this for initialization void Start() { //测试极小堆 print("------------------测试极小堆------------------"); int capicity = 100; int n = 10; int[] arr = AlgorithmsHelp.generateRandomArray(n, 1, 20); MinHeap <int> minHeap = new MinHeap <int> (100); MinHeap <int> minarrHeap = new MinHeap <int> (arr, 100); for (int i = 0; i != n; i++) { minHeap.Insert(arr[i]); } minHeap.print(); minarrHeap.print(); string str = ""; while (minHeap.Size() > 0) { str += minHeap.ExtraMinItem() + " "; } Debug.Log(str); testChangeInNormalHeap(minarrHeap); print("------------------------------------------"); print("------------------测试极小索引堆------------------"); //测试极小索引堆 arr = AlgorithmsHelp.generateRandomArray(n, 1, 20); IndexMinHeap <int> minIndexHeap = new IndexMinHeap <int>(100); IndexMinHeap <int> minarrIndexHeap = new IndexMinHeap <int>(arr, 100); for (int i = 0; i != n; i++) { minIndexHeap.Insert(arr[i]); } minIndexHeap.print(); minarrIndexHeap.print(); str = ""; while (minIndexHeap.Size() > 0) { str += minIndexHeap.ExtraMinItem() + " "; } print("从小到大排序 " + str); testChangeInIndexHeap(minarrIndexHeap); // 测试极大堆 // int capicity = 100; // int n = 10; // Heap<int> maxHeap = new Heap<int> (100); // int[] arr = AlgorithmsHelp.generateRandomArray (n,1,20); // for (int i = 0; i != n; i++) { // maxHeap.Insert (arr[i]); // } // maxHeap.printData (); // // string str = ""; // for (int i = 0; i != n; i++) { // str +=maxHeap.ExtractBigItem()+" "; // } // print ("data[] : " +str); }