Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
        /// <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]);
        }
Exemplo n.º 3
0
        /// <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);
        }
Exemplo n.º 4
0
        /// <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);
        }
Exemplo n.º 5
0
        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");
        }
Exemplo n.º 6
0
        /// <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);
        }
Exemplo n.º 7
0
        /// <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);
        }
Exemplo n.º 8
0
        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();
            }
        }
Exemplo n.º 9
0
        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");
            }
        }
Exemplo n.º 10
0
        /// <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);
        }
Exemplo n.º 11
0
        /// <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);
        }
Exemplo n.º 12
0
        /// <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);
        }
Exemplo n.º 13
0
        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);
            }
        }
Exemplo n.º 14
0
        /// <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);
        }
Exemplo n.º 15
0
        /// <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);
        }
Exemplo n.º 16
0
        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");
        }
Exemplo n.º 17
0
        // 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));
        }
Exemplo n.º 18
0
        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);
            }
        }
Exemplo n.º 19
0
 /// <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));
 }
Exemplo n.º 20
0
        /// <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);
        }