Exemplo n.º 1
0
        /// <summary>
        /// Returns a random simple digraph containing <tt>V</tt> vertices and <tt>E</tt> edges.
        /// </summary>
        /// <param name="v">V the number of vertices</param>
        /// <param name="e">E the number of vertices</param>
        /// <returns>a random simple digraph on <tt>V</tt> vertices, containing a total of <tt>E</tt> edges</returns>
        /// <exception cref="ArgumentException">if no such simple digraph exists</exception>
        public static Digraph Simple(int v, int e)
        {
            if (e > (long)v * (v - 1))
            {
                throw new ArgumentException("Too many edges");
            }
            if (e < 0)
            {
                throw new ArgumentException("Too few edges");
            }
            var g   = new Digraph(v);
            var set = new SET <EdgeD>();

            while (g.E < e)
            {
                var ve   = StdRandom.Uniform(v);
                var we   = StdRandom.Uniform(v);
                var edge = new EdgeD(ve, we);
                if ((ve != we) && !set.Contains(edge))
                {
                    set.Add(edge);
                    g.AddEdge(ve, we);
                }
            }
            return(g);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Returns a random simple DAG containing <tt>V</tt> vertices and <tt>E</tt> edges.
        /// Note: it is not uniformly selected at random among all such DAGs.
        /// </summary>
        /// <param name="v">V the number of vertices</param>
        /// <param name="e">E the number of vertices</param>
        /// <returns>a random simple DAG on <tt>V</tt> vertices, containing a total of <tt>E</tt> 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");
            }
            var g        = new Digraph(v);
            var set      = new SET <EdgeD>();
            var vertices = new int[v];

            for (var i = 0; i < v; i++)
            {
                vertices[i] = i;
            }
            StdRandom.Shuffle(vertices);
            while (g.E < e)
            {
                var ve   = StdRandom.Uniform(v);
                var we   = StdRandom.Uniform(v);
                var edge = new EdgeD(ve, we);
                if ((ve < we) && !set.Contains(edge))
                {
                    set.Add(edge);
                    g.AddEdge(vertices[ve], vertices[we]);
                }
            }
            return(g);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Returns a random rooted-out DAG on <tt>V</tt> vertices and <tt>E</tt> 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">V the number of vertices</param>
        /// <param name="e">E the number of edges</param>
        /// <returns>a random rooted-out DAG on <tt>V</tt> vertices and <tt>E</tt> 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");
            }
            var g   = new Digraph(v);
            var set = new SET <EdgeD>();

            // fix a topological order
            var vertices = new int[v];

            for (var 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 (var ve = 0; ve < v - 1; ve++)
            {
                var we   = StdRandom.Uniform(ve + 1, v);
                var edge = new EdgeD(we, ve);
                set.Add(edge);
                g.AddEdge(vertices[we], vertices[ve]);
            }

            while (g.E < e)
            {
                var ve   = StdRandom.Uniform(v);
                var we   = StdRandom.Uniform(v);
                var edge = new EdgeD(we, ve);
                if ((ve < we) && !set.Contains(edge))
                {
                    set.Add(edge);
                    g.AddEdge(vertices[we], vertices[ve]);
                }
            }
            return(g);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Returns a random simple digraph on <tt>V</tt> vertices, <tt>E</tt>
        /// edges and (at least) <tt>c</tt> strong components. The vertices are randomly
        /// assigned integer labels between <tt>0</tt> and <tt>c-1</tt> (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">V the number of vertices</param>
        /// <param name="e">E the number of edges</param>
        /// <param name="c">c the (maximum) number of strong components</param>
        /// <returns>a random simple digraph on <tt>V</tt> vertices and <tt>E</tt> edges, with (at most) <tt>c</tt> strong components</returns>
        /// <exception cref="ArgumentException">if <tt>c</tt> is larger than <tt>V</tt></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
            var g = new Digraph(v);

            // edges added to G (to avoid duplicate edges)
            var set = new SET <EdgeD>();

            var label = new int[v];

            for (var i = 0; i < v; i++)
            {
                label[i] = StdRandom.Uniform(c);
            }

            // make all vertices with label c a strong component by
            // combining a rooted in-tree and a rooted out-tree
            for (var i = 0; i < c; i++)
            {
                // how many vertices in component c
                var count = 0;
                for (var ii = 0; ii < g.V; ii++)
                {
                    if (label[ii] == i)
                    {
                        count++;
                    }
                }

                // if (count == 0) System.err.println("less than desired number of strong components");

                var vertices = new int[count];
                var j        = 0;
                for (var jj = 0; jj < v; jj++)
                {
                    if (label[jj] == i)
                    {
                        vertices[j++] = jj;
                    }
                }
                StdRandom.Shuffle(vertices);

                // rooted-in tree with root = vertices[count-1]
                for (var ve = 0; ve < count - 1; ve++)
                {
                    var we   = StdRandom.Uniform(ve + 1, count);
                    var edge = new EdgeD(we, ve);
                    set.Add(edge);
                    g.AddEdge(vertices[we], vertices[ve]);
                }

                // rooted-out tree with root = vertices[count-1]
                for (var ve = 0; ve < count - 1; ve++)
                {
                    var we   = StdRandom.Uniform(ve + 1, count);
                    var edge = new EdgeD(ve, we);
                    set.Add(edge);
                    g.AddEdge(vertices[ve], vertices[we]);
                }
            }

            while (g.E < e)
            {
                var ve   = StdRandom.Uniform(v);
                var we   = StdRandom.Uniform(v);
                var edge = new EdgeD(ve, we);
                if (!set.Contains(edge) && ve != we && label[ve] <= label[we])
                {
                    set.Add(edge);
                    g.AddEdge(ve, we);
                }
            }

            return(g);
        }