/// <summary> /// Returns a random simple DAG containing <c>V</c> vertices and <c>E</c> edges. /// Note: it is not uniformly selected at random among all such DAGs.</summary> /// <param name="V">the number of vertices</param> /// <param name="E">the number of vertices</param> /// <returns>a random simple DAG on <c>V</c> vertices, containing a total /// of <c>E</c> edges</returns> /// <exception cref="ArgumentException">if no such simple DAG exists</exception> /// public static Digraph Dag(int V, int E) { if (E > (long)V * (V - 1) / 2) { throw new ArgumentException("Too many edges"); } if (E < 0) { throw new ArgumentException("Too few edges"); } Digraph G = new Digraph(V); SET <Edge> set = new SET <Edge>(); int[] vertices = new int[V]; for (int i = 0; i < V; i++) { vertices[i] = i; } StdRandom.Shuffle(vertices); while (G.E < E) { int v = StdRandom.Uniform(V); int w = StdRandom.Uniform(V); Edge e = new Edge(v, w); if ((v < w) && !set.Contains(e)) { set.Add(e); G.AddEdge(vertices[v], vertices[w]); } } return(G); }
/// <summary> /// Rearranges the array so that a[k] contains the kth smallest key; /// a[0] through a[k-1] are OrderHelper.Less than (or equal to) a[k]; and /// a[k+1] through a[N-1] are greater than (or equal to) a[k].</summary> /// <param name="a">a the array</param> /// <param name="k">k find the kth smallest</param> /// <returns>the rearranged array</returns> /// <exception cref="IndexOutOfRangeException"> if k is out of range</exception> /// public static IComparable Select(IComparable[] a, int k) { if (k < 0 || k >= a.Length) { throw new IndexOutOfRangeException("Selected element out of bounds"); } StdRandom.Shuffle(a); int lo = 0, hi = a.Length - 1; while (hi > lo) { int i = partition(a, lo, hi); if (i > k) { hi = i - 1; } else if (i < k) { lo = i + 1; } else { return(a[i]); } } return(a[lo]); }
/// <summary> /// Returns a uniformly random <c>k</c>-regular graph on <c>V</c> vertices /// (not necessarily simple). The graph is simple with probability only about e^(-k^2/4), /// which is tiny when k = 14.</summary> /// <param name="V">the number of vertices in the graph</param> /// <param name="k">the k-regular value</param> /// <returns>a uniformly random <c>k</c>-regular graph on <c>V</c> vertices.</returns> /// public static Graph Regular(int V, int k) { if (V * k % 2 != 0) { throw new ArgumentException("Number of vertices * k must be even"); } Graph G = new Graph(V); // create k copies of each vertex int[] vertices = new int[V * k]; for (int v = 0; v < V; v++) { for (int j = 0; j < k; j++) { vertices[v + V * j] = v; } } // pick a random perfect matching StdRandom.Shuffle(vertices); for (int i = 0; i < V * k / 2; i++) { G.AddEdge(vertices[2 * i], vertices[2 * i + 1]); } return(G); }
/// <summary> /// Returns a wheel graph on <c>V</c> vertices.</summary> /// <param name="V">the number of vertices in the wheel</param> /// <returns>a wheel graph on <c>V</c> vertices: a single vertex connected to /// every vertex in a cycle on <c>V-1</c> vertices</returns> /// public static Graph Wheel(int V) { if (V <= 1) { throw new ArgumentException("Number of vertices must be at least 2"); } Graph G = new Graph(V); int[] vertices = new int[V]; for (int i = 0; i < V; i++) { vertices[i] = i; } StdRandom.Shuffle(vertices); // simple cycle on V-1 vertices for (int i = 1; i < V - 1; i++) { G.AddEdge(vertices[i], vertices[i + 1]); } G.AddEdge(vertices[V - 1], vertices[1]); // connect vertices[0] to every vertex on cycle for (int i = 1; i < V; i++) { G.AddEdge(vertices[0], vertices[i]); } return(G); }
public static void MainTest(string[] args) { int V = int.Parse(args[0]); int E = int.Parse(args[1]); // Eulerian cycle Graph G1 = GraphGenerator.EulerianCycle(V, E); EulerianCycle.UnitTest(G1, "Eulerian cycle"); // Eulerian path Graph G2 = GraphGenerator.EulerianPath(V, E); EulerianCycle.UnitTest(G2, "Eulerian path"); // empty graph Graph G3 = new Graph(V); EulerianCycle.UnitTest(G3, "empty graph"); // self loop Graph G4 = new Graph(V); int v4 = StdRandom.Uniform(V); G4.AddEdge(v4, v4); EulerianCycle.UnitTest(G4, "single self loop"); // union of two disjoint cycles Graph H1 = GraphGenerator.EulerianCycle(V / 2, E / 2); Graph H2 = GraphGenerator.EulerianCycle(V - V / 2, E - E / 2); int[] perm = new int[V]; for (int i = 0; i < V; i++) { perm[i] = i; } StdRandom.Shuffle(perm); Graph G5 = new Graph(V); for (int v = 0; v < H1.V; v++) { foreach (int w in H1.Adj(v)) { G5.AddEdge(perm[v], perm[w]); } } for (int v = 0; v < H2.V; v++) { foreach (int w in H2.Adj(v)) { G5.AddEdge(perm[V / 2 + v], perm[V / 2 + w]); } } EulerianCycle.UnitTest(G5, "Union of two disjoint cycles"); // random digraph Graph G6 = GraphGenerator.Simple(V, E); EulerianCycle.UnitTest(G6, "simple graph"); }
/// <summary> /// Returns a random simple bipartite graph on <c>V1</c> and <c>V2</c> vertices, /// containing each possible edge with probability <c>p</c>.</summary> /// <param name="V1">the number of vertices in one partition</param> /// <param name="V2">the number of vertices in the other partition</param> /// <param name="p">the probability that the graph contains an edge with one endpoint in either side</param> /// <returns>a random simple bipartite graph on <c>V1</c> and <c>V2</c> vertices, /// containing each possible edge with probability <c>p</c></returns> /// <exception cref="ArgumentException">if probability is not between 0 and 1</exception> /// public static Graph Bipartite(int V1, int V2, double p) { if (p < 0.0 || p > 1.0) { throw new ArgumentException("Probability must be between 0 and 1"); } int[] vertices = new int[V1 + V2]; for (int i = 0; i < V1 + V2; i++) { vertices[i] = i; } StdRandom.Shuffle(vertices); Graph G = new Graph(V1 + V2); for (int i = 0; i < V1; i++) { for (int j = 0; j < V2; j++) { if (StdRandom.Bernoulli(p)) { G.AddEdge(vertices[i], vertices[V1 + j]); } } } return(G); }
/// <summary> /// Returns a random simple bipartite graph on <c>V1</c> and <c>V2</c> vertices /// with <c>E</c> edges.</summary> /// <param name="V1">the number of vertices in one partition</param> /// <param name="V2">the number of vertices in the other partition</param> /// <param name="E">the number of edges</param> /// <returns>a random simple bipartite graph on <c>V1</c> and <c>V2</c> vertices, /// containing a total of <c>E</c> edges</returns> /// <exception cref="ArgumentException">if no such simple bipartite graph exists</exception> /// public static Graph Bipartite(int V1, int V2, int E) { if (E > (long)V1 * V2) { throw new ArgumentException("Too many edges for bipartite graphs"); } if (E < 0) { throw new ArgumentException("Too few edges for bipartite graphs"); } Graph G = new Graph(V1 + V2); int[] vertices = new int[V1 + V2]; for (int i = 0; i < V1 + V2; i++) { vertices[i] = i; } StdRandom.Shuffle(vertices); SET <Edge> set = new SET <Edge>(); while (G.E < E) { int i = StdRandom.Uniform(V1); int j = V1 + StdRandom.Uniform(V2); Edge e = new Edge(vertices[i], vertices[j]); if (!set.Contains(e)) { set.Add(e); G.AddEdge(vertices[i], vertices[j]); } } return(G); }
public static void MainTest(string[] args) { int n = int.Parse(args[0]); if (args.Length == 2) { StdRandom.Seed = int.Parse(args[1]); } double[] probabilities = { 0.5, 0.3, 0.1, 0.1 }; int[] frequencies = { 5, 3, 1, 1 }; string[] a = "A B C D E F G".Split(' '); Console.WriteLine("seed = " + StdRandom.Seed); for (int i = 0; i < n; i++) { Console.Write("{0} ", StdRandom.Uniform(100)); Console.Write("{0:F5} ", StdRandom.Uniform(10.0, 99.0)); Console.Write("{0} ", StdRandom.Bernoulli(0.5)); Console.Write("{0:F5} ", StdRandom.Gaussian(9.0, 0.2)); Console.Write("{0} ", StdRandom.Discrete(probabilities)); Console.Write("{0} ", StdRandom.Discrete(frequencies)); StdRandom.Shuffle(a); foreach (string s in a) { Console.Write(s); } Console.WriteLine(); } }
public static void MainTest(string[] args) { // create random DAG with V vertices and E edges; then add F random edges int V = int.Parse(args[0]); int E = int.Parse(args[1]); int F = int.Parse(args[2]); EdgeWeightedDigraph G = new EdgeWeightedDigraph(V); int[] vertices = new int[V]; for (int i = 0; i < V; i++) { vertices[i] = i; } StdRandom.Shuffle(vertices); for (int i = 0; i < E; i++) { int v, w; do { v = StdRandom.Uniform(V); w = StdRandom.Uniform(V); } while (v >= w); double weight = StdRandom.Uniform(); G.AddEdge(new DirectedEdge(v, w, weight)); } // add F extra edges for (int i = 0; i < F; i++) { int v = StdRandom.Uniform(V); int w = StdRandom.Uniform(V); double weight = StdRandom.Uniform(0.0, 1.0); G.AddEdge(new DirectedEdge(v, w, weight)); } Console.WriteLine(G); // find a directed cycle EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(G); if (finder.HasCycle) { Console.Write("Cycle: "); foreach (DirectedEdge e in finder.GetCycle()) { Console.Write(e + " "); } Console.WriteLine(); } // or give topologial sort else { Console.WriteLine("No directed cycle"); } }
/// <summary> /// Returns a complete binary tree digraph on <c>V</c> vertices.</summary> /// <param name="V">the number of vertices in the binary tree</param> /// <returns>a digraph that is a complete binary tree on <c>V</c> vertices</returns> /// public static Digraph BinaryTree(int V) { Digraph G = new Digraph(V); int[] vertices = new int[V]; for (int i = 0; i < V; i++) { vertices[i] = i; } StdRandom.Shuffle(vertices); for (int i = 1; i < V; i++) { G.AddEdge(vertices[i], vertices[(i - 1) / 2]); } return(G); }
/// <summary> /// Returns a path digraph on <c>V</c> vertices.</summary> /// <param name="V">the number of vertices in the path</param> /// <returns>a digraph that is a directed path on <c>V</c> vertices</returns> /// public static Digraph Path(int V) { Digraph G = new Digraph(V); int[] vertices = new int[V]; for (int i = 0; i < V; i++) { vertices[i] = i; } StdRandom.Shuffle(vertices); for (int i = 0; i < V - 1; i++) { G.AddEdge(vertices[i], vertices[i + 1]); } return(G); }
/// <summary> /// Returns a cycle graph on <c>V</c> vertices.</summary> /// <param name="V">the number of vertices in the cycle</param> /// <returns>a cycle graph on <c>V</c> vertices</returns> /// public static Graph Cycle(int V) { Graph G = new Graph(V); int[] vertices = new int[V]; for (int i = 0; i < V; i++) { vertices[i] = i; } StdRandom.Shuffle(vertices); for (int i = 0; i < V - 1; i++) { G.AddEdge(vertices[i], vertices[i + 1]); } G.AddEdge(vertices[V - 1], vertices[0]); return(G); }
public static void MainTest(string[] args) { TextInput StdIn = new TextInput(); string[] a = StdIn.ReadAllStrings(); OrderHelper.Show(a); // shuffle StdRandom.Shuffle(a); // display results again using select Console.WriteLine(); for (int i = 0; i < a.Length; i++) { string ith = (string)Quick.Select(a, i); Console.WriteLine(ith); } }
/// <summary> /// Returns a random rooted-out DAG on <c>V</c> vertices and <c>E</c> edges. /// A rooted out-tree is a DAG in which every vertex is reachable from a /// single vertex. /// The DAG returned is not chosen uniformly at random among all such DAGs.</summary> /// <param name="V">the number of vertices</param> /// <param name="E">the number of edges</param> /// <returns>a random rooted-out DAG on <c>V</c> vertices and <c>E</c> edges</returns> /// public static Digraph RootedOutDAG(int V, int E) { if (E > (long)V * (V - 1) / 2) { throw new ArgumentException("Too many edges"); } if (E < V - 1) { throw new ArgumentException("Too few edges"); } Digraph G = new Digraph(V); SET <Edge> set = new SET <Edge>(); // fix a topological order int[] vertices = new int[V]; for (int i = 0; i < V; i++) { vertices[i] = i; } StdRandom.Shuffle(vertices); // one edge pointing from each vertex, other than the root = vertices[V-1] for (int v = 0; v < V - 1; v++) { int w = StdRandom.Uniform(v + 1, V); Edge e = new Edge(w, v); set.Add(e); G.AddEdge(vertices[w], vertices[v]); } while (G.E < E) { int v = StdRandom.Uniform(V); int w = StdRandom.Uniform(V); Edge e = new Edge(w, v); if ((v < w) && !set.Contains(e)) { set.Add(e); G.AddEdge(vertices[w], vertices[v]); } } return(G); }
/// <summary> /// Returns a star graph on <c>V</c> vertices.</summary> /// <param name="V">the number of vertices in the star</param> /// <returns>a star graph on <c>V</c> vertices: a single vertex connected to /// every other vertex</returns> /// public static Graph Star(int V) { if (V <= 0) { throw new ArgumentException("Number of vertices must be at least 1"); } Graph G = new Graph(V); int[] vertices = new int[V]; for (int i = 0; i < V; i++) { vertices[i] = i; } StdRandom.Shuffle(vertices); // connect vertices[0] to every other vertex for (int i = 1; i < V; i++) { G.AddEdge(vertices[0], vertices[i]); } return(G); }
public static void MainTest(string[] args) { int V = int.Parse(args[0]); int E = int.Parse(args[1]); // Eulerian cycle Digraph G1 = DigraphGenerator.EulerianCycle(V, E); DirectedEulerianCycle.UnitTest(G1, "Eulerian cycle"); // Eulerian path Digraph G2 = DigraphGenerator.EulerianPath(V, E); DirectedEulerianCycle.UnitTest(G2, "Eulerian path"); // empty digraph Digraph G3 = new Digraph(V); DirectedEulerianCycle.UnitTest(G3, "empty digraph"); // self loop Digraph G4 = new Digraph(V); int v4 = StdRandom.Uniform(V); G4.AddEdge(v4, v4); DirectedEulerianCycle.UnitTest(G4, "single self loop"); // union of two disjoint cycles Digraph H1 = DigraphGenerator.EulerianCycle(V / 2, E / 2); Digraph H2 = DigraphGenerator.EulerianCycle(V - V / 2, E - E / 2); int[] perm = new int[V]; for (int i = 0; i < V; i++) { perm[i] = i; } StdRandom.Shuffle(perm); Digraph G5 = new Digraph(V); for (int v = 0; v < H1.V; v++) { foreach (int w in H1.Adj(v)) { G5.AddEdge(perm[v], perm[w]); } } for (int v = 0; v < H2.V; v++) { foreach (int w in H2.Adj(v)) { G5.AddEdge(perm[V / 2 + v], perm[V / 2 + w]); } } DirectedEulerianCycle.UnitTest(G5, "Union of two disjoint cycles"); // random digraph Digraph G6 = DigraphGenerator.Simple(V, E); DirectedEulerianCycle.UnitTest(G6, "simple digraph"); // 4-vertex digraph - no data file //Digraph G7 = new Digraph(new TextInput("eulerianD.txt")); //DirectedEulerianCycle.UnitTest(G7, "4-vertex Eulerian digraph"); }
// TODO: Add a generic verion /// <summary> /// Rearranges the array in ascending order, using the natural order.</summary> /// <param name="a">a the array to be sorted</param> /// public static void Sort(IComparable[] a) { StdRandom.Shuffle(a); sort(a, 0, a.Length - 1); Debug.Assert(OrderHelper.IsSorted(a)); }
public static void MainTest(string[] args) { // insert a bunch of strings string[] strings = { "it", "was", "the", "best", "of", "times", "it", "was", "the", "worst" }; IndexMaxPQ <string> pq = new IndexMaxPQ <string>(strings.Length); for (int i = 0; i < strings.Length; i++) { pq.Insert(i, strings[i]); } // print each key using the iterator foreach (int i in pq) { Console.WriteLine(i + " " + strings[i]); } Console.WriteLine(); // increase or decrease the key for (int i = 0; i < strings.Length; i++) { if (StdRandom.Uniform() < 0.5) { pq.IncreaseKey(i, strings[i] + strings[i]); } else { pq.DecreaseKey(i, strings[i].Substring(0, 1)); } } // delete and print each key while (!pq.IsEmpty) { string key = pq.MaxKey; int i = pq.DelMax(); Console.WriteLine(i + " " + key); } Console.WriteLine(); // reinsert the same strings for (int i = 0; i < strings.Length; i++) { pq.Insert(i, strings[i]); } Console.WriteLine("Deleting in randome order"); // delete them in random order int[] perm = new int[strings.Length]; for (int i = 0; i < strings.Length; i++) { perm[i] = i; } StdRandom.Shuffle(perm); for (int i = 0; i < perm.Length; i++) { string key = pq.KeyOf(perm[i]); pq.Delete(perm[i]); Console.WriteLine(perm[i] + " " + key); } }
/// <summary> /// Rearranges the array of strings in ascending order.</summary> /// <param name="a">the array to be sorted</param> /// public static void Sort(string[] a) { StdRandom.Shuffle(a); sort(a, 0, a.Length - 1, 0); Debug.Assert(isSorted(a)); }
/// <summary> /// Returns a random simple digraph on <c>V</c> vertices, <c>E</c> /// edges and (at least) <c>c</c> strong components. The vertices are randomly /// assigned integer labels between <c>0</c> and <c>c-1</c> (corresponding to /// strong components). Then, a strong component is creates among the vertices /// with the same label. Next, random edges (either between two vertices with /// the same labels or from a vetex with a smaller label to a vertex with a /// larger label). The number of components will be equal to the number of /// distinct labels that are assigned to vertices.</summary> /// <param name="V">the number of vertices</param> /// <param name="E">the number of edges</param> /// <param name="c">the (maximum) number of strong components</param> /// <returns>a random simple digraph on <c>V</c> vertices and /// <c>E</c> edges, with (at most) <c>c</c> strong components</returns> /// <exception cref="ArgumentException">if <c>c</c> is larger than <c>V</c></exception> /// public static Digraph Strong(int V, int E, int c) { if (c >= V || c <= 0) { throw new ArgumentException("Number of components must be between 1 and V"); } if (E <= 2 * (V - c)) { throw new ArgumentException("Number of edges must be at least 2(V-c)"); } if (E > (long)V * (V - 1) / 2) { throw new ArgumentException("Too many edges"); } // the digraph Digraph G = new Digraph(V); // edges added to G (to avoid duplicate edges) SET <Edge> set = new SET <Edge>(); int[] label = new int[V]; for (int v = 0; v < V; v++) { label[v] = StdRandom.Uniform(c); } // make all vertices with label c a strong component by // combining a rooted in-tree and a rooted out-tree for (int i = 0; i < c; i++) { // how many vertices in component c int count = 0; for (int v = 0; v < G.V; v++) { if (label[v] == i) { count++; } } // if (count == 0) System.err.println("less than desired number of strong components"); int[] vertices = new int[count]; int j = 0; for (int v = 0; v < V; v++) { if (label[v] == i) { vertices[j++] = v; } } StdRandom.Shuffle(vertices); // rooted-in tree with root = vertices[count-1] for (int v = 0; v < count - 1; v++) { int w = StdRandom.Uniform(v + 1, count); Edge e = new Edge(w, v); set.Add(e); G.AddEdge(vertices[w], vertices[v]); } // rooted-out tree with root = vertices[count-1] for (int v = 0; v < count - 1; v++) { int w = StdRandom.Uniform(v + 1, count); Edge e = new Edge(v, w); set.Add(e); G.AddEdge(vertices[v], vertices[w]); } } while (G.E < E) { int v = StdRandom.Uniform(V); int w = StdRandom.Uniform(V); Edge e = new Edge(v, w); if (!set.Contains(e) && v != w && label[v] <= label[w]) { set.Add(e); G.AddEdge(v, w); } } return(G); }