public void TestIndexMinHeap() { int n = 1000000; Random random = new Random(); var heap = new IndexMinHeap <int>(n); for (int i = 0; i < n; i++) { heap.Add((int)(random.Next() * n)); } var arr = new int[n]; for (var i = 0; i < n; i++) { arr[i] = heap.ExtractMin(); } var success = true; for (var i = 1; i < n; i++) { if (arr[i - 1] > arr[i]) { success = false; } } Assert.AreEqual(true, success); }
// 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); }
public KruskalMST(IGraph <TWeight> graph) { G = graph; ipq = new IndexMinHeap <Edge <TWeight> >(2 * G.E); marked = new bool[G.V]; MSTEdges = new List <Edge <TWeight> >(); for (var i = 0; i < G.V; i++) { foreach (Edge <TWeight> e in G.GetAdjIterator(i)) { ipq.Add(e); } } var uf = new UnionFind(G.V); while (!ipq.IsEmpty() && MSTEdges.Count < graph.V - 1) { var e = ipq.ExtractMin(); if (uf.IsConnected(e.V, e.W)) { continue; } MSTEdges.Add(e); uf.UnionElements(e.V, e.W); } var value = 0.0; var converter = TypeDescriptor.GetConverter(typeof(TWeight)); foreach (var edge in MSTEdges) { value += (double)converter.ConvertTo(edge.Weight, typeof(double)); } MSTWeight = (TWeight)converter.ConvertTo(value, typeof(TWeight)); }
static void Main(string[] args) { // 使用两种图的储存方式来读取文件 string fileName = "TextG1.txt"; SparseGraph graph = new SparseGraph(13, false); ReadGraph readGraph = new ReadGraph(graph, fileName); Console.WriteLine("test g1 in sparse graph "); graph.Show(); Console.WriteLine(); DenseGraph graph1 = new DenseGraph(13, false); ReadGraph readGraph1 = new ReadGraph(graph1, fileName); Console.WriteLine("test g1 in dense graph "); graph1.Show(); Console.WriteLine("==========================================="); DenseGraph graph2 = new DenseGraph(13, false); ReadGraph readGraph2 = new ReadGraph(graph2, fileName); Path path = new Path(graph2, 0); Console.WriteLine("test path g1 in dense graph "); path.ShowPath(4); Console.WriteLine("==========================================="); WeightedDenseGraph <double> wgraph3 = new WeightedDenseGraph <double>(8, false); ReadWeightedGraph readGraph3 = new ReadWeightedGraph(wgraph3, "testG1.txt"); Console.WriteLine("test in weighted dense graph "); wgraph3.Show(); Console.WriteLine("==========================================="); SparseWeightedGraph <double> wgraph4 = new SparseWeightedGraph <double>(8, false); ReadWeightedGraph readGraph4 = new ReadWeightedGraph(wgraph4, "testG1.txt"); Console.WriteLine("test in weighted sparse graph "); wgraph4.Show(); Console.WriteLine("Test MinHeap"); int n = 100000; MinHeap <int> heap = new MinHeap <int>(n); Random rand = new Random(); for (int i = 0; i < n; i++) { heap.Add(rand.Next(n)); } List <int> list = new List <int>(); for (int i = 0; i < n; i++) { list.Add(heap.ExtractMin()); } for (int i = 0; i < n - 1; i++) { if (list[i] > list[i + 1]) { throw new Exception("MinHeap error"); } } Console.WriteLine("==========================================="); Console.WriteLine("Test MST"); SparseWeightedGraph <double> wgraph5 = new SparseWeightedGraph <double>(8, false); ReadWeightedGraph readGraph5 = new ReadWeightedGraph(wgraph5, "testG1.txt"); LazyPrimeMST <double> mst = new LazyPrimeMST <double>(wgraph5); List <Edge <double> > mstPath = mst.MstEdges(); for (int i = 0; i < mstPath.Count; i++) { Console.WriteLine(mstPath[i]); } Console.WriteLine("Test Index MinHeap"); IndexMinHeap <int> heap1 = new IndexMinHeap <int>(n); for (int i = 0; i < n; i++) { heap1.Add(i, rand.Next(n)); } for (int i = 0; i < n / 2; i++) { heap1.Update(i, rand.Next(n)); } List <int> list1 = new List <int>(); for (int i = 0; i < n; i++) { list1.Add(heap1.ExtractMin()); } for (int i = 0; i < n - 1; i++) { if (list1[i] > list1[i + 1]) { throw new Exception("IndexMinHeap error"); } } Console.WriteLine("==========================================="); Console.WriteLine("Test MST Optimization"); SparseWeightedGraph <double> wgraph6 = new SparseWeightedGraph <double>(8, false); ReadWeightedGraph readGraph6 = new ReadWeightedGraph(wgraph6, "testG1.txt"); PrimMST <double> mst1 = new PrimMST <double>(wgraph6); List <Edge <double> > mstPath1 = mst1.MstEdges(); for (int i = 0; i < mstPath1.Count; i++) { Console.WriteLine(mstPath1[i]); } }