public void Run()
        {
            // create random bipartite graph with V vertices and E edges; then add F random edges
            const int vv = 20;
            const int e = 30;
            const int f = 5;

            var graph = new Graph(vv);
            var vertices = new int[vv];
            for (var i = 0; i < vv; i++)
                vertices[i] = i;
            StdRandom.Shuffle(vertices);
            for (var i = 0; i < e; i++)
            {
                var v = StdRandom.Uniform(vv / 2);
                var w = StdRandom.Uniform(vv / 2);
                graph.AddEdge(vertices[v], vertices[vv / 2 + w]);
            }

            // add F extra edges
            for (var i = 0; i < f; i++)
            {
                var v = StdRandom.Uniform(vv);
                var w = StdRandom.Uniform(vv);
                graph.AddEdge(v, w);
            }

            Console.WriteLine(graph);
            var b = new Bipartite(graph);
            if (b.IsBipartite())
            {
                Console.WriteLine("Graph is bipartite");
                for (var v = 0; v < graph.V; v++)
                {
                    Console.WriteLine(v + ": " + b.Color(v));
                }
            }
            else
            {
                Console.Write("Graph has an odd-length cycle: ");
                foreach (int x in b.OddCycle())
                {
                    Console.Write(x + " ");
                }
                Console.WriteLine();
            }

            Console.ReadLine();
        }
        public void Run()
        {
            const int vv = 20;
            const int e = 30;

            // Eulerian cycle
            var g1 = GraphGenerator.EulerianCycle(vv, e);
            EulerianCycle.UnitTest(g1, "Eulerian cycle");

            // Eulerian path
            var g2 = GraphGenerator.EulerianCycle(vv, e);
            EulerianCycle.UnitTest(g2, "Eulerian path");

            // empty graph
            var g3 = new Graph(vv);
            EulerianCycle.UnitTest(g3, "empty graph");

            // self loop
            var g4 = new Graph(vv);
            var v4 = StdRandom.Uniform(vv);
            g4.AddEdge(v4, v4);
            EulerianCycle.UnitTest(g4, "single self loop");

            // union of two disjoint cycles
            var h1 = GraphGenerator.EulerianCycle(vv / 2, e / 2);
            var h2 = GraphGenerator.EulerianCycle(vv - vv / 2, e - e / 2);
            var perm = new int[vv];
            for (var i = 0; i < vv; i++)
                perm[i] = i;
            StdRandom.Shuffle(perm);
            var g5 = new Graph(vv);
            for (var v = 0; v < h1.V; v++)
                foreach (int w in h1.Adj(v))
                    g5.AddEdge(perm[v], perm[w]);
            for (var v = 0; v < h2.V; v++)
                foreach (int w in h2.Adj(v))
                    g5.AddEdge(perm[vv / 2 + v], perm[vv / 2 + w]);
            EulerianCycle.UnitTest(g5, "Union of two disjoint cycles");

            // random digraph
            var g6 = GraphGenerator.Simple(vv, e);
            EulerianCycle.UnitTest(g6, "simple graph");

            Console.ReadLine();
        }
Example #3
0
 /// <summary>
 /// Returns a complete binary tree graph on <tt>V</tt> vertices.
 /// </summary>
 /// <param name="v">V the number of vertices in the binary tree</param>
 /// <returns>a complete binary tree graph on <tt>V</tt> vertices</returns>
 public static Graph BinaryTree(int v)
 {
     var g = new Graph(v);
     var vertices = new int[v];
     for (var i = 0; i < v; i++)
         vertices[i] = i;
     StdRandom.Shuffle(vertices);
     for (var i = 1; i < v; i++)
     {
         g.AddEdge(vertices[i], vertices[(i - 1) / 2]);
     }
     return g;
 }
Example #4
0
        private readonly ST<string, Integer> _st; // string -> index

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a graph from a file using the specified delimiter.
        /// Each line in the file contains
        /// the name of a vertex, followed by a list of the names
        /// of the vertices adjacent to that vertex, separated by the delimiter.
        /// </summary>
        /// <param name="lines">array of string lines</param>
        /// <param name="delimiter">delimiter the delimiter between fields</param>
        public SymbolGraph(IList<string> lines, char delimiter)
        {
            _st = new ST<string, Integer>();

            // First pass builds the index by reading strings to associate
            // distinct strings with an index
            // while (in.hasNextLine()) {
            foreach (var line in lines)
            {
                var a = line.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var word in a)
                {
                    if (!_st.Contains(word))
                        _st.Put(word, _st.Size());
                }
            }

            Console.WriteLine("Done reading");

            // inverted index to get string keys in an aray
            _keys = new string[_st.Size()];
            foreach (var name in _st.Keys())
            {
                _keys[_st.Get(name)] = name;
            }

            // second pass builds the graph by connecting first vertex on each
            // line to all others
            G = new Graph(_st.Size());
            foreach (var line in lines)
            {
                var a = line.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
                int v = _st.Get(a[0]);
                for (var i = 1; i < a.Length; i++)
                {
                    int w = _st.Get(a[i]);
                    G.AddEdge(v, w);
                }
            }
        }
        public void Run()
        {
            const int v = 20;
            const int e = 30;

            // Eulerian cycle
            var g1 = GraphGenerator.EulerianCycle(v, e);
            EulerianPath.UnitTest(g1, "Eulerian cycle");

            // Eulerian path
            var g2 = GraphGenerator.EulerianPath(v, e);
            EulerianPath.UnitTest(g2, "Eulerian path");

            // add one random edge
            var g3 = new Graph(g2);
            g3.AddEdge(StdRandom.Uniform(v), StdRandom.Uniform(v));
            EulerianPath.UnitTest(g3, "one random edge added to Eulerian path");

            // self loop
            var g4 = new Graph(v);
            var v4 = StdRandom.Uniform(v);
            g4.AddEdge(v4, v4);
            EulerianPath.UnitTest(g4, "single self loop");

            // single edge
            var g5 = new Graph(v);
            g5.AddEdge(StdRandom.Uniform(v), StdRandom.Uniform(v));
            EulerianPath.UnitTest(g5, "single edge");

            // empty graph
            var g6 = new Graph(v);
            EulerianPath.UnitTest(g6, "empty graph");

            // random graph
            var g7 = GraphGenerator.Simple(v, e);
            EulerianPath.UnitTest(g7, "simple graph");

            Console.ReadLine();
        }
Example #6
0
        /// <summary>
        /// Returns a random simple bipartite graph on <tt>V1</tt> and <tt>V2</tt> vertices
        /// with <tt>E</tt> edges.
        /// </summary>
        /// <param name="v1">V1 the number of vertices in one partition</param>
        /// <param name="v2">V2 the number of vertices in the other partition</param>
        /// <param name="e">E the number of edges</param>
        /// <returns>a random simple bipartite graph on <tt>V1</tt> and <tt>V2</tt> vertices, containing a total of <tt>E</tt> 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");
            if (e < 0) throw new ArgumentException("Too few edges");
            var g = new Graph(v1 + v2);

            var vertices = new int[v1 + v2];
            for (var i = 0; i < v1 + v2; i++)
                vertices[i] = i;
            StdRandom.Shuffle(vertices);

            var set = new SET<EdgeU>();
            while (g.E < e)
            {
                var i = StdRandom.Uniform(v1);
                var j = v1 + StdRandom.Uniform(v2);
                var edge = new EdgeU(vertices[i], vertices[j]);
                if (set.Contains(edge)) continue;
                set.Add(edge);
                g.AddEdge(vertices[i], vertices[j]);
            }
            return g;
        }
Example #7
0
 /// <summary>
 /// Returns a random simple bipartite graph on <tt>V1</tt> and <tt>V2</tt> vertices,
 /// containing each possible edge with probability <tt>p</tt>.
 /// </summary>
 /// <param name="v1">V1 the number of vertices in one partition</param>
 /// <param name="v2">V2 the number of vertices in the other partition</param>
 /// <param name="p">p the probability that the graph contains an edge with one endpoint in either side</param>
 /// <returns>a random simple bipartite graph on <tt>V1</tt> and <tt>V2</tt> vertices, containing each possible edge with probability <tt>p</tt></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");
     var vertices = new int[v1 + v2];
     for (var i = 0; i < v1 + v2; i++)
         vertices[i] = i;
     StdRandom.Shuffle(vertices);
     var g = new Graph(v1 + v2);
     for (var i = 0; i < v1; i++)
         for (var j = 0; j < v2; j++)
             if (StdRandom.Bernoulli(p))
                 g.AddEdge(vertices[i], vertices[v1 + j]);
     return g;
 }
Example #8
0
        /// <summary>
        /// Returns a wheel graph on <tt>V</tt> vertices.
        /// </summary>
        /// <param name="v">V the number of vertices in the wheel</param>
        /// <returns>a wheel graph on <tt>V</tt> vertices: a single vertex connected to every vertex in a cycle on <tt>V-1</tt> vertices</returns>
        public static Graph Wheel(int v)
        {
            if (v <= 1) throw new ArgumentException("Number of vertices must be at least 2");
            var g = new Graph(v);
            var vertices = new int[v];
            for (var i = 0; i < v; i++)
                vertices[i] = i;
            StdRandom.Shuffle(vertices);

            // simple cycle on V-1 vertices
            for (var 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 (var i = 1; i < v; i++)
            {
                g.AddEdge(vertices[0], vertices[i]);
            }

            return g;
        }
Example #9
0
        /// <summary>
        /// Returns a uniformly random tree on <tt>V</tt> vertices.
        /// This algorithm uses a Prufer sequence and takes time proportional to <em>V log V</em>.
        /// 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>
        /// <param name="v">V the number of vertices in the tree</param>
        /// <returns>a uniformly random tree on <tt>V</tt> vertices</returns>
        public static Graph Tree(int v)
        {
            var 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
            var prufer = new int[v - 2];
            for (var i = 0; i < v - 2; i++)
                prufer[i] = StdRandom.Uniform(v);

            // degree of vertex v = 1 + number of times it appers in Prufer sequence
            var degree = new int[v];
            for (var vi = 0; vi < v; vi++)
                degree[vi] = 1;
            for (var i = 0; i < v - 2; i++)
                degree[prufer[i]]++;

            // pq contains all vertices of degree 1
            var pq = new MinPQ<Integer>();
            for (var vi = 0; vi < v; vi++)
                if (degree[vi] == 1) pq.Insert(vi);

            // repeatedly delMin() degree 1 vertex that has the minimum index
            for (var i = 0; i < v - 2; i++)
            {
                int vmin = pq.DelMin();
                g.AddEdge(vmin, prufer[i]);
                degree[vmin]--;
                degree[prufer[i]]--;
                if (degree[prufer[i]] == 1) pq.Insert(prufer[i]);
            }
            g.AddEdge(pq.DelMin(), pq.DelMin());
            return g;
        }
Example #10
0
        /// <summary>
        /// Returns a star graph on <tt>V</tt> vertices.
        /// </summary>
        /// <param name="v">V the number of vertices in the star</param>
        /// <returns>a star graph on <tt>V</tt> 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");
            var g = new Graph(v);
            var vertices = new int[v];
            for (var i = 0; i < v; i++)
                vertices[i] = i;
            StdRandom.Shuffle(vertices);

            // connect vertices[0] to every other vertex
            for (var i = 1; i < v; i++)
            {
                g.AddEdge(vertices[0], vertices[i]);
            }

            return g;
        }
Example #11
0
 /// <summary>
 /// Returns a random simple graph 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 edges</param>
 /// <returns> random simple graph on <tt>V</tt> vertices, containing a total of <tt>E</tt> edges</returns>
 /// <exception cref="ArgumentException">if no such simple graph exists</exception>
 public static Graph Simple(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 Graph(v);
     var set = new SET<EdgeU>();
     while (g.E < e)
     {
         var ve = StdRandom.Uniform(v);
         var we = StdRandom.Uniform(v);
         var edge = new EdgeU(ve, we);
         if ((ve == we) || set.Contains(edge)) continue;
         set.Add(edge);
         g.AddEdge(ve, we);
     }
     return g;
 }
Example #12
0
        /// <summary>
        /// Returns a uniformly random <tt>k</tt>-regular graph on <tt>V</tt> 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">V the number of vertices in the graph</param>
        /// <param name="k"></param>
        /// <returns>a uniformly random <tt>k</tt>-regular graph on <tt>V</tt> 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");
            var g = new Graph(v);

            // create k copies of each vertex
            var vertices = new int[v * k];
            for (var vi = 0; vi < v; vi++)
            {
                for (var j = 0; j < k; j++)
                {
                    vertices[vi + v * j] = vi;
                }
            }

            // pick a random perfect matching
            StdRandom.Shuffle(vertices);
            for (var i = 0; i < v * k / 2; i++)
            {
                g.AddEdge(vertices[2 * i], vertices[2 * i + 1]);
            }
            return g;
        }
Example #13
0
 /// <summary>
 /// Returns a path graph on <tt>V</tt> vertices.
 /// </summary>
 /// <param name="v">V the number of vertices in the path</param>
 /// <returns>a path graph on <tt>V</tt> vertices</returns>
 public static Graph Path(int v)
 {
     var g = new Graph(v);
     var vertices = new int[v];
     for (var i = 0; i < v; i++)
         vertices[i] = i;
     StdRandom.Shuffle(vertices);
     for (var i = 0; i < v - 1; i++)
     {
         g.AddEdge(vertices[i], vertices[i + 1]);
     }
     return g;
 }
Example #14
0
 /// <summary>
 /// Returns an Eulerian path graph on <tt>V</tt> vertices.
 /// </summary>
 /// <param name="v">V the number of vertices in the path</param>
 /// <param name="e">E the number of edges in the path</param>
 /// <returns>a graph that is an Eulerian path on <tt>V</tt> vertices and <tt>E</tt> edges</returns>
 /// <exception cref="ArgumentException">if either V &le; 0 or E &lt; 0</exception>
 public static Graph EulerianPath(int v, int e)
 {
     if (e < 0)
         throw new ArgumentException("negative number of edges");
     if (v <= 0)
         throw new ArgumentException("An Eulerian path must have at least one vertex");
     var g = new Graph(v);
     var vertices = new int[e + 1];
     for (var i = 0; i < e + 1; i++)
         vertices[i] = StdRandom.Uniform(v);
     for (var i = 0; i < e; i++)
     {
         g.AddEdge(vertices[i], vertices[i + 1]);
     }
     return g;
 }
Example #15
0
 /// <summary>
 /// Returns an Eulerian cycle graph on <tt>V</tt> vertices.
 /// </summary>
 /// <param name="v">V the number of vertices in the cycle</param>
 /// <param name="e">E the number of edges in the cycle</param>
 /// <returns>a graph that is an Eulerian cycle on <tt>V</tt> vertices and <tt>E</tt> edges</returns>
 /// <exception cref="ArgumentException">if either V &le; 0 or E &le; 0</exception>
 public static Graph EulerianCycle(int v, int e)
 {
     if (e <= 0)
         throw new ArgumentException("An Eulerian cycle must have at least one edge");
     if (v <= 0)
         throw new ArgumentException("An Eulerian cycle must have at least one vertex");
     var g = new Graph(v);
     var vertices = new int[e];
     for (var i = 0; i < e; i++)
         vertices[i] = StdRandom.Uniform(v);
     for (var i = 0; i < e - 1; i++)
     {
         g.AddEdge(vertices[i], vertices[i + 1]);
     }
     g.AddEdge(vertices[e - 1], vertices[0]);
     return g;
 }
        /// <summary>
        /// Determines whether a digraph has an Eulerian path using necessary
        /// and sufficient conditions (without computing the path itself):
        ///    - indegree(v) = outdegree(v) for every vertex,
        ///      except one vertex v may have outdegree(v) = indegree(v) + 1
        ///      (and one vertex v may have indegree(v) = outdegree(v) + 1)
        ///    - the graph is connected, when viewed as an undirected graph
        ///      (ignoring isolated vertices)
        /// This method is solely for unit testing.
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        private static bool HasEulerianPath(Digraph g)
        {
            if (g.E == 0) return true;

            // Condition 1: indegree(v) == outdegree(v) for every vertex,
            // except one vertex may have outdegree(v) = indegree(v) + 1
            var deficit = 0;
            for (var v = 0; v < g.V; v++)
                if (g.Outdegree(v) > g.Indegree(v))
                    deficit += (g.Outdegree(v) - g.Indegree(v));
            if (deficit > 1) return false;

            // Condition 2: graph is connected, ignoring isolated vertices
            var h = new Graph(g.V);
            for (var v = 0; v < g.V; v++)
                foreach (int w in g.Adj(v))
                    h.AddEdge(v, w);

            // check that all non-isolated vertices are connected
            var s = NonIsolatedVertex(g);
            var bfs = new BreadthFirstPaths(h, s);
            for (var v = 0; v < g.V; v++)
                if (h.Degree(v) > 0 && !bfs.HasPathTo(v))
                    return false;

            return true;
        }
Example #17
0
 /// <summary>
 /// Returns a random simple graph on <tt>V</tt> vertices, with an 
 /// edge between any two vertices with probability <tt>p</tt>. This is sometimes
 /// referred to as the Erdos-Renyi random graph model.
 /// </summary>
 /// <param name="v">V the number of vertices</param>
 /// <param name="p">p the probability of choosing an edge</param>
 /// <returns>a random simple graph on <tt>V</tt> vertices, with an edge between any two vertices with probability <tt>p</tt></returns>
 /// <exception cref="ArgumentException">if probability is not between 0 and 1</exception>
 public static Graph Simple(int v, double p)
 {
     if (p < 0.0 || p > 1.0)
         throw new ArgumentException("Probability must be between 0 and 1");
     var g = new Graph(v);
     for (var vi = 0; vi < v; vi++)
         for (var wi = vi + 1; wi < v; wi++)
             if (StdRandom.Bernoulli(p))
                 g.AddEdge(vi, wi);
     return g;
 }