// For a complete description, see // http://www.proofwiki.org/wiki/Labeled_Tree_from_Prüfer_Sequence // http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.36.6484&rep=rep1&type=pdf /// <summary> /// Returns a uniformly random tree on <c>V</c> vertices. /// This algorithm uses a Prufer sequence and takes time proportional to <c>V log V</c>.</summary> /// <param name="V">the number of vertices in the tree</param> /// <returns>a uniformly random tree on <c>V</c> vertices</returns> /// public static Graph Tree(int V) { Graph G = new Graph(V); // special case if (V == 1) { return(G); } // Cayley's theorem: there are V^(V-2) labeled trees on V vertices // Prufer sequence: sequence of V-2 values between 0 and V-1 // Prufer's proof of Cayley's theorem: Prufer sequences are in 1-1 // with labeled trees on V vertices int[] prufer = new int[V - 2]; for (int i = 0; i < V - 2; i++) { prufer[i] = StdRandom.Uniform(V); } // degree of vertex v = 1 + number of times it appers in Prufer sequence int[] degree = new int[V]; for (int v = 0; v < V; v++) { degree[v] = 1; } for (int i = 0; i < V - 2; i++) { degree[prufer[i]]++; } // pq contains all vertices of degree 1 MinPQ <int> pq = new MinPQ <int>(); for (int v = 0; v < V; v++) { if (degree[v] == 1) { pq.Insert(v); } } // repeatedly delMin() degree 1 vertex that has the minimum index for (int i = 0; i < V - 2; i++) { int v = pq.DelMin(); G.AddEdge(v, prufer[i]); degree[v]--; degree[prufer[i]]--; if (degree[prufer[i]] == 1) { pq.Insert(prufer[i]); } } G.AddEdge(pq.DelMin(), pq.DelMin()); return(G); }
private LinkedQueue <Edge> mst = new LinkedQueue <Edge>(); // edges in MST /// <summary> /// Compute a minimum spanning tree (or forest) of an edge-weighted graph.</summary> /// <param name="G">the edge-weighted graph</param> /// public KruskalMST(EdgeWeightedGraph G) { // more efficient to build heap by passing array of edges MinPQ <Edge> pq = new MinPQ <Edge>(); foreach (Edge e in G.Edges()) { pq.Insert(e); } // run greedy algorithm UF uf = new UF(G.V); while (!pq.IsEmpty && mst.Count < G.V - 1) { Edge e = pq.DelMin(); int v = e.Either; int w = e.Other(v); if (!uf.Connected(v, w)) { // v-w does not create a cycle uf.Union(v, w); // merge v and w components mst.Enqueue(e); // add edge e to mst weight += e.Weight; } } // check optimality conditions Debug.Assert(check(G)); }
// additional test static void TopInts() { int[] allInts = { 12, 11, 8, 7, 9, 5, 4, 3, 2, 29, 23, 1, 24, 30, 9, 4, 88, 5, 100, 29, 23, 5, 99, 87, 22, 111 }; MinPQ <int> pq0 = new MinPQ <int>(allInts); int M = allInts.Length / 3; MinPQ <int> pq = new MinPQ <int>(M + 1); Console.WriteLine("Top {0} is ", M); foreach (var n in allInts) { pq.Insert(n); Console.WriteLine("Min is {0}", pq.Min); // remove minimum if M+1 entries on the PQ if (pq.Count > M) { pq.DelMin(); } } // print entries on PQ in reverse order LinkedStack <int> stack = new LinkedStack <int>(); foreach (int n in pq) { stack.Push(n); } foreach (int n in stack) { Console.WriteLine(n); } Console.WriteLine("These are the top elements"); }
public static void MainTest(string[] args) { int M = int.Parse(args[0]); MinPQ <Transaction> pq = new MinPQ <Transaction>(M + 1); TextInput StdIn = new TextInput(); while (!StdIn.IsEmpty) { // Create an entry from the next line and put on the PQ. string line = StdIn.ReadLine(); Transaction transaction = new Transaction(line); pq.Insert(transaction); // remove minimum if M+1 entries on the PQ if (pq.Count > M) { pq.DelMin(); } } // top M entries are on the PQ // print entries on PQ in reverse order LinkedStack <Transaction> stack = new LinkedStack <Transaction>(); foreach (Transaction transaction in pq) { stack.Push(transaction); } foreach (Transaction transaction in stack) { Console.WriteLine(transaction); } }
// build the Huffman trie given frequencies private static Node buildTrie(int[] freq) { // initialze priority queue with singleton trees MinPQ <Node> pq = new MinPQ <Node>(); for (int i = 0; i < R; i++) { if (freq[i] > 0) { pq.Insert(new Node((char)i, freq[i], null, null)); } } // special case in case there is only one character with a nonzero frequency if (pq.Count == 1) { if (freq[ZERO] == 0) { pq.Insert(new Node(ZERO, 0, null, null)); } else { pq.Insert(new Node(ONE, 0, null, null)); } } // merge two smallest trees while (pq.Count > 1) { Node left = pq.DelMin(); Node right = pq.DelMin(); Node parent = new Node(ZERO, left.freq + right.freq, left, right); pq.Insert(parent); } return(pq.DelMin()); }
/// <summary> /// The event handler to support frame-based animation /// </summary> /// <param name="sender">the window host</param> /// <param name="ev">event argument, usually ignored</param> public void Update(object sender, EventArgs ev) { // the main event-driven simulation loop if (!pq.IsEmpty) { // get impending event, discard if invalidated Event e = pq.DelMin(); if (!e.IsValid()) { return; } Particle a = e.A; Particle b = e.B; // physical collision, so update positions, and then simulation clock for (int i = 0; i < particles.Length; i++) { particles[i].Move(e.Time - t); } t = e.Time; // process event if (a != null && b != null) { a.BounceOff(b); // particle-particle collision } else if (a != null && b == null) { a.BounceOffVerticalWall(); // particle-wall collision } else if (a == null && b != null) { b.BounceOffHorizontalWall(); // particle-wall collision } else if (a == null && b == null) { redraw(limit); // redraw event } // update the priority queue with new collisions involving a or b predict(a, limit); predict(b, limit); } }
public static void MainTest(string[] args) { TextInput StdIn = new TextInput(); MinPQ <string> pq = new MinPQ <string>(); while (!StdIn.IsEmpty) { string item = StdIn.ReadString(); if (!item.Equals("-")) { pq.Insert(item); } else if (!pq.IsEmpty) { Console.Write(pq.DelMin() + " "); } } Console.WriteLine("(" + pq.Count + " left on pq)"); }
// run Prim's algorithm private void prim(EdgeWeightedGraph G, int s) { scan(G, s); while (!pq.IsEmpty) { // better to stop when mst has V-1 edges Edge e = pq.DelMin(); // smallest edge on pq int v = e.Either, w = e.Other(v); // two endpoints Debug.Assert(marked[v] || marked[w]); if (marked[v] && marked[w]) { continue; // lazy, both v and w already scanned } mst.Enqueue(e); // add e to MST weight += e.Weight; if (!marked[v]) { scan(G, v); // v becomes part of tree } if (!marked[w]) { scan(G, w); // w becomes part of tree } } }