Ejemplo n.º 1
0
        private void Dfs(Graph g, int u, int v)
        {
            _marked[v] = true;
            foreach (int w in g.Adj(v))
            {

                // short circuit if cycle already found
                if (_cycle != null) return;

                if (!_marked[w])
                {
                    _edgeTo[w] = v;
                    Dfs(g, v, w);
                }

                // check for cycle (but disregard reverse of edge leading to v)
                else if (w != u)
                {
                    _cycle = new Collections.Stack<Integer>();
                    for (var x = v; x != w; x = _edgeTo[x])
                    {
                        _cycle.Push(x);
                    }
                    _cycle.Push(w);
                    _cycle.Push(v);
                }
            }
        }
Ejemplo n.º 2
0
        private readonly int _s; // source vertex

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Computes a path between <tt>s</tt> and every other vertex in graph <tt>G</tt>.
        /// </summary>
        /// <param name="g">g the graph</param>
        /// <param name="s">s the source vertex</param>
        public DepthFirstPaths(Graph g, int s)
        {
            _s = s;
            _edgeTo = new int[g.V];
            _marked = new bool[g.V];
            Dfs(g, s);
        }
Ejemplo n.º 3
0
        private readonly bool[] _marked; // marked[v] = is there an s-v path

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Computes the shortest path between the source vertex <tt>s</tt>
        /// and every other vertex in the graph <tt>G</tt>.
        /// </summary>
        /// <param name="g">g the graph</param>
        /// <param name="s">s the source vertex</param>
        public BreadthFirstPaths(Graph g, int s)
        {
            _marked = new bool[g.V];
            _distTo = new int[g.V];
            _edgeTo = new int[g.V];
            Bfs(g, s);

            //assert check(G, s);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Computes the shortest path between any one of the source vertices in <tt>sources</tt>
 /// and every other vertex in graph <tt>G</tt>.
 /// </summary>
 /// <param name="g">g the graph</param>
 /// <param name="sources">sources the source vertices</param>
 public BreadthFirstPaths(Graph g, IEnumerable<Integer> sources)
 {
     _marked = new bool[g.V];
     _distTo = new int[g.V];
     _edgeTo = new int[g.V];
     for (var v = 0; v < g.V; v++)
         _distTo[v] = INFINITY;
     Bfs(g, sources);
 }
Ejemplo n.º 5
0
        public void Run()
        {
            Console.WriteLine("Choose file:"); // Prompt
            Console.WriteLine("1 - tinyG.txt"); // Prompt
            Console.WriteLine("2 - mediumG.txt"); // Prompt
            Console.WriteLine("or quit"); // Prompt

            var fileNumber = Console.ReadLine();
            var fieName = string.Empty;
            switch (fileNumber)
            {
                case "1":
                    fieName = "tinyG.txt";
                    break;
                case "2":
                    fieName = "mediumG.txt";
                    break;
                case "quit":
                    return;
                default:
                    return;
            }

            var @in = new In($"Files\\Graphs\\{fieName}");
            var lines = @in.ReadAllLines();

            var lineIterator = 0;
            var v = 0;
            var e = 0;
            var edges = new List<EdgeU>();
            foreach (var line in lines)
            {
                if (lineIterator == 0)
                {
                    v = Convert.ToInt32(line);
                }
                if (lineIterator == 1)
                {
                    e = Convert.ToInt32(line);
                }
                if (lineIterator > 1)
                {
                    var lineSplitted = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
                    var ve = Convert.ToInt32(lineSplitted[0]);
                    var we = Convert.ToInt32(lineSplitted[1]);
                    var edge = new EdgeU(ve, we);
                    edges.Add(edge);
                }

                lineIterator++;
            }

            var graph = new Graph(v, e, edges);
            Console.WriteLine(graph);
            Console.ReadLine();
        }
Ejemplo n.º 6
0
 /// <summary>
 /// depth first search from v
 /// </summary>
 /// <param name="g"></param>
 /// <param name="v"></param>
 private void Dfs(Graph g, int v)
 {
     _marked[v] = true;
     foreach (int w in g.Adj(v))
     {
         if (_marked[w]) continue;
         _edgeTo[w] = v;
         Dfs(g, w);
     }
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Determines whether the undirected graph <tt>G</tt> has a cycle and,
 /// if so, finds such a cycle.
 /// </summary>
 /// <param name="g">g the undirected graph</param>
 public Cycle(Graph g)
 {
     if (HasSelfLoop(g)) return;
     if (HasParallelEdges(g)) return;
     _marked = new bool[g.V];
     _edgeTo = new int[g.V];
     for (var v = 0; v < g.V; v++)
         if (!_marked[v])
             Dfs(g, -1, v);
 }
Ejemplo n.º 8
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;
 }
Ejemplo n.º 9
0
        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();
        }
Ejemplo n.º 10
0
        private bool _isBipartite; // is the graph bipartite?

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Determines whether an undirected graph is bipartite and finds either a
        /// bipartition or an odd-length cycle.
        /// </summary>
        /// <param name="g">g the graph</param>
        public Bipartite(Graph g)
        {
            _isBipartite = true;
            _color = new bool[g.V];
            _marked = new bool[g.V];
            _edgeTo = new int[g.V];

            for (var v = 0; v < g.V; v++)
            {
                if (!_marked[v])
                {
                    Dfs(g, v);
                }
            }
            //assert check(G);
        }
Ejemplo n.º 11
0
        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();
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Initializes a new graph that is a deep copy of <tt>G</tt>.
 /// </summary>
 /// <param name="g">g the graph to copy</param>
 public Graph(Graph g)
     : this(g.V)
 {
     E = g.E;
     for (var v = 0; v < g.V; v++)
     {
         // reverse so that adjacency list is in same order as original
         var reverse = new Collections.Stack<Integer>();
         foreach (int w in g._adj[v])
         {
             reverse.Push(w);
         }
         foreach (int w in reverse)
         {
             _adj[v].Add(w);
         }
     }
 }
Ejemplo n.º 13
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);
                }
            }
        }
Ejemplo n.º 14
0
        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();
        }
Ejemplo n.º 15
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;
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Computes the vertices connected to the source vertex <tt>s</tt> in the graph <tt>G</tt>.
        /// </summary>
        /// <param name="g">g the graph</param>
        /// <param name="s">s the source vertex</param>
        public NonrecursiveDFS(Graph g, int s)
        {
            _marked = new bool[g.V];

            // to be able to iterate over each adjacency list, keeping track of which
            // vertex in each adjacency list needs to be explored next
            var adj = new IEnumerator<Integer>[g.V];
            for (var v = 0; v < g.V; v++)
                adj[v] = g.Adj(v).GetEnumerator();

            // depth-first search using an explicit stack
            var stack = new Collections.Stack<Integer>();
            _marked[s] = true;
            stack.Push(s);
            while (!stack.IsEmpty())
            {
                int v = stack.Peek();
                if (adj[v].MoveNext())
                {
                    int w = adj[v].Current;
                    // StdOut.printf("check %d\n", w);
                    if (!_marked[w])
                    {
                        // discovered vertex w for the first time
                        _marked[w] = true;
                        // edgeTo[w] = v;
                        stack.Push(w);
                        // StdOut.printf("dfs(%d)\n", w);
                    }
                }
                else
                {
                    // StdOut.printf("%d done\n", v);
                    stack.Pop();
                }
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// check optimality conditions for single source
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        /// <returns></returns>
        private bool Check(Graph g, int s)
        {
            // check that the distance of s = 0
            if (_distTo[s] != 0)
            {
                Console.WriteLine("distance of source " + s + " to itself = " + _distTo[s]);
                return false;
            }

            // check that for each edge v-w dist[w] <= dist[v] + 1
            // provided v is reachable from s
            for (var v = 0; v < g.V; v++)
            {
                foreach (int w in g.Adj(v))
                {
                    if (HasPathTo(v) != HasPathTo(w))
                    {
                        Console.WriteLine("edge " + v + "-" + w);
                        Console.WriteLine("hasPathTo(" + v + ") = " + HasPathTo(v));
                        Console.WriteLine("hasPathTo(" + w + ") = " + HasPathTo(w));
                        return false;
                    }
                    if (HasPathTo(v) && (_distTo[w] > _distTo[v] + 1))
                    {
                        Console.WriteLine("edge " + v + "-" + w);
                        Console.WriteLine("distTo[" + v + "] = " + _distTo[v]);
                        Console.WriteLine("distTo[" + w + "] = " + _distTo[w]);
                        return false;
                    }
                }
            }

            // check that v = edgeTo[w] satisfies distTo[w] + distTo[v] + 1
            // provided v is reachable from s
            for (var w = 0; w < g.V; w++)
            {
                if (!HasPathTo(w) || w == s) continue;
                var v = _edgeTo[w];
                if (_distTo[w] == _distTo[v] + 1) continue;
                Console.WriteLine("shortest path edge " + v + "-" + w);
                Console.WriteLine("distTo[" + v + "] = " + _distTo[v]);
                Console.WriteLine("distTo[" + w + "] = " + _distTo[w]);
                return false;
            }

            return true;
        }
Ejemplo n.º 18
0
 /// <summary>
 /// breadth-first search from multiple sources
 /// </summary>
 /// <param name="g"></param>
 /// <param name="sources"></param>
 private void Bfs(Graph g, IEnumerable<Integer> sources)
 {
     var q = new Collections.Queue<Integer>();
     foreach (int s in sources)
     {
         _marked[s] = true;
         _distTo[s] = 0;
         q.Enqueue(s);
     }
     while (!q.IsEmpty())
     {
         int v = q.Dequeue();
         foreach (int w in g.Adj(v))
         {
             if (_marked[w]) continue;
             _edgeTo[w] = v;
             _distTo[w] = _distTo[v] + 1;
             _marked[w] = true;
             q.Enqueue(w);
         }
     }
 }
Ejemplo n.º 19
0
        /// <summary>
        /// breadth-first search from a single source
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        private void Bfs(Graph g, int s)
        {
            var q = new Collections.Queue<Integer>();
            for (var v = 0; v < g.V; v++)
                _distTo[v] = INFINITY;
            _distTo[s] = 0;
            _marked[s] = true;
            q.Enqueue(s);

            while (!q.IsEmpty())
            {
                int v = q.Dequeue();
                foreach (int w in g.Adj(v))
                {
                    if (_marked[w]) continue;
                    _edgeTo[w] = v;
                    _distTo[w] = _distTo[v] + 1;
                    _marked[w] = true;
                    q.Enqueue(w);
                }
            }
        }
Ejemplo n.º 20
0
        /// <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;
        }
Ejemplo n.º 21
0
        private bool Check(Graph g)
        {
            // graph is bipartite
            if (_isBipartite)
            {
                for (var v = 0; v < g.V; v++)
                {
                    foreach (int w in g.Adj(v))
                    {
                        if (_color[v] != _color[w]) continue;
                        Console.Error.WriteLine($"edge {v}-{w} with {v} and {w} in same side of bipartition\n");
                        return false;
                    }
                }
            }

            // graph has an odd-length cycle
            else
            {
                // verify cycle
                int first = -1, last = -1;
                foreach (int v in OddCycle())
                {
                    if (first == -1) first = v;
                    last = v;
                }
                if (first == last) return true;
                Console.Error.WriteLine($"cycle begins with {first} and ends with {last}{Environment.NewLine}");
                return false;
            }

            return true;
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Determines whether a graph has an Eulerian path using necessary
        /// and sufficient conditions (without computing the path itself):
        ///    - degree(v) is even for every vertex, except for possibly two
        ///    - the graph is connected (ignoring isolated vertices)
        /// This method is solely for unit testing.
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        private static bool HasEulerianPath(Graph g)
        {
            if (g.E == 0) return true;

            // Condition 1: degree(v) is even except for possibly two
            var oddDegreeVertices = 0;
            for (var v = 0; v < g.V; v++)
                if (g.Degree(v) % 2 != 0)
                    oddDegreeVertices++;
            if (oddDegreeVertices > 2) return false;

            // Condition 2: graph is connected, ignoring isolated vertices
            var s = NonIsolatedVertex(g);
            var bfs = new BreadthFirstPaths(g, s);
            for (var v = 0; v < g.V; v++)
                if (g.Degree(v) > 0 && !bfs.HasPathTo(v))
                    return false;

            return true;
        }
Ejemplo n.º 23
0
        private readonly Collections.Stack<Integer> _path; // Eulerian path; null if no suh path

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Computes an Eulerian path in the specified graph, if one exists.
        /// </summary>
        /// <param name="g">g the graph</param>
        public EulerianPath(Graph g)
        {
            // find vertex from which to start potential Eulerian path:
            // a vertex v with odd degree(v) if it exits;
            // otherwise a vertex with degree(v) > 0
            var oddDegreeVertices = 0;
            var s = NonIsolatedVertex(g);
            for (var v = 0; v < g.V; v++)
            {
                if (g.Degree(v) % 2 != 0)
                {
                    oddDegreeVertices++;
                    s = v;
                }
            }

            // graph can't have an Eulerian path
            // (this condition is needed for correctness)
            if (oddDegreeVertices > 2) return;

            // special case for graph with zero edges (has a degenerate Eulerian path)
            if (s == -1) s = 0;

            // create local view of adjacency lists, to iterate one vertex at a time
            // the helper Edge data type is used to avoid exploring both copies of an edge v-w
            var adj = new Collections.Queue<EdgeW>[g.V];
            for (var v = 0; v < g.V; v++)
                adj[v] = new Collections.Queue<EdgeW>();

            for (var v = 0; v < g.V; v++)
            {
                var selfLoops = 0;
                foreach (int w in g.Adj(v))
                {
                    // careful with self loops
                    if (v == w)
                    {
                        if (selfLoops % 2 == 0)
                        {
                            var e = new EdgeW(v, w, 0);
                            adj[v].Enqueue(e);
                            adj[w].Enqueue(e);
                        }
                        selfLoops++;
                    }
                    else if (v < w)
                    {
                        var e = new EdgeW(v, w, 0);
                        adj[v].Enqueue(e);
                        adj[w].Enqueue(e);
                    }
                }
            }

            // initialize stack with any non-isolated vertex
            var stack = new Collections.Stack<Integer>();
            stack.Push(s);

            // greedily search through edges in iterative DFS style
            _path = new Collections.Stack<Integer>();
            while (!stack.IsEmpty())
            {
                int v = stack.Pop();
                while (!adj[v].IsEmpty())
                {
                    var edge = adj[v].Dequeue();
                    if (edge.IsUsed) continue;
                    edge.IsUsed = true;
                    stack.Push(v);
                    v = edge.Other(v);
                }
                // push vertex with no more leaving edges to path
                _path.Push(v);
            }

            // check if all edges are used
            if (_path.Size() != g.E + 1)
                _path = null;

            //assert certifySolution(G);
        }
Ejemplo n.º 24
0
        public void Run()
        {
            Console.WriteLine("Choose file:"); // Prompt
            Console.WriteLine("1 - tinyCG.txt"); // Prompt
            Console.WriteLine("2 - mediumG.txt"); // Prompt
            Console.WriteLine("or quit"); // Prompt

            var fileNumber = Console.ReadLine();
            var fieName = string.Empty;
            switch (fileNumber)
            {
                case "1":
                    fieName = "tinyCG.txt";
                    break;
                case "2":
                    fieName = "mediumG.txt";
                    break;
                case "quit":
                    return;
                default:
                    return;
            }

            var @in = new In($"Files\\Graphs\\{fieName}");
            var lines = @in.ReadAllLines();

            var lineIterator = 0;
            var v = 0;
            var e = 0;
            var edges = new List<EdgeU>();
            foreach (var line in lines)
            {
                if (lineIterator == 0)
                {
                    v = Convert.ToInt32(line);
                }
                if (lineIterator == 1)
                {
                    e = Convert.ToInt32(line);
                }
                if (lineIterator > 1)
                {
                    var lineSplitted = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    var ve = Convert.ToInt32(lineSplitted[0]);
                    var we = Convert.ToInt32(lineSplitted[1]);
                    var edge = new EdgeU(ve, we);
                    edges.Add(edge);
                }

                lineIterator++;
            }

            var graph = new Graph(v, e, edges);
            Console.WriteLine(graph);

            const int s = 0;
            var dfs1 = new DepthFirstPaths(graph, s);
            for (var vi = 0; vi < graph.V; vi++)
            {
                if (dfs1.HasPathTo(vi))
                {
                    Console.Write($"{s} to {vi}:  ");
                    foreach (int x in dfs1.PathTo(vi))
                    {
                        if (x == s) Console.Write(x);
                        else Console.Write($"-{x}");
                    }
                    Console.WriteLine();
                }

                else
                {
                    Console.WriteLine($"{s} to {v}:  not connected{Environment.NewLine}");
                }

            }

            //Console.WriteLine("------------------------------------------------");

            Console.ReadLine();
        }
Ejemplo n.º 25
0
        // check that solution is correct
        public bool CertifySolution(Graph g)
        {
            // internal consistency check
            if (HasEulerianPath() == (Path() == null)) return false;

            // hashEulerianPath() returns correct value
            if (HasEulerianPath() != HasEulerianPath(g)) return false;

            // nothing else to check if no Eulerian path
            if (_path == null) return true;

            // check that path() uses correct number of edges
            if (_path.Size() != g.E + 1) return false;

            // check that path() is a path in G
            // TODO

            return true;
        }
Ejemplo n.º 26
0
        public void Run()
        {
            Console.WriteLine("Choose file:"); // Prompt
            Console.WriteLine("1 - tinyG.txt"); // Prompt
            Console.WriteLine("2 - mediumG.txt"); // Prompt
            //Console.WriteLine("3 - largeG.zip"); // Prompt
            Console.WriteLine("or quit"); // Prompt

            var fileNumber = Console.ReadLine();
            var fieName = string.Empty;
            switch (fileNumber)
            {
                case "1":
                    fieName = "tinyG.txt";
                    break;
                case "2":
                    fieName = "mediumG.txt";
                    break;
                //case "3":
                //    fieName = "largeG.zip";
                //    break;
                case "quit":
                    return;
                default:
                    return;
            }

            var @in = new In($"Files\\Graphs\\{fieName}");
            var lines = !fieName.EndsWith("zip") ? @in.ReadAllLines() : @in.ReadAllLinesFromZip();

            var lineIterator = 0;
            var v = 0;
            var e = 0;
            var edges = new List<EdgeU>();
            foreach (var line in lines)
            {
                if (lineIterator == 0)
                {
                    v = Convert.ToInt32(line);
                }
                if (lineIterator == 1)
                {
                    e = Convert.ToInt32(line);
                }
                if (lineIterator > 1)
                {
                    var lineSplitted = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    var ve = Convert.ToInt32(lineSplitted[0]);
                    var we = Convert.ToInt32(lineSplitted[1]);
                    var edge = new EdgeU(ve, we);
                    edges.Add(edge);
                }

                lineIterator++;
            }

            var graph = new Graph(v, e, edges);
            if (fileNumber != "3")
            {
                Console.WriteLine(graph);
            }

            var finder = new Cycle(graph);
            if (finder.HasCycle())
            {
                foreach (int vi in finder.CycleIterator())
                {
                    Console.Write($"{vi} ");
                }
                Console.WriteLine();
            }
            else
            {
                Console.WriteLine("Graph is acyclic");
            }

            Console.ReadLine();
        }
Ejemplo n.º 27
0
        private void Bfs(Graph g, int s)
        {
            var q = new Collections.Queue<Integer>();
            _color[s] = WHITE;
            _marked[s] = true;
            q.Enqueue(s);

            while (!q.IsEmpty())
            {
                int v = q.Dequeue();
                foreach (int w in g.Adj(v))
                {
                    if (!_marked[w])
                    {
                        _marked[w] = true;
                        _edgeTo[w] = v;
                        _color[w] = !_color[v];
                        q.Enqueue(w);
                    }
                    else if (_color[w] == _color[v])
                    {
                        _isBipartite = false;

                        // to form odd cycle, consider s-v path and s-w path
                        // and let x be closest node to v and w common to two paths
                        // then (w-x path) + (x-v path) + (edge v-w) is an odd-length cycle
                        // Note: distTo[v] == distTo[w];
                        _cycle = new Collections.Queue<Integer>();
                        var stack = new Collections.Stack<Integer>();
                        int x = v, y = w;
                        while (x != y)
                        {
                            stack.Push(x);
                            _cycle.Enqueue(y);
                            x = _edgeTo[x];
                            y = _edgeTo[y];
                        }
                        stack.Push(x);
                        while (!stack.IsEmpty())
                            _cycle.Enqueue(stack.Pop());
                        _cycle.Enqueue(w);
                        return;
                    }
                }
            }
        }
Ejemplo n.º 28
0
        private void Dfs(Graph g, int v)
        {
            _marked[v] = true;
            foreach (int w in g.Adj(v))
            {

                // short circuit if odd-length cycle found
                if (_cycle != null) return;

                // found uncolored vertex, so recur
                if (!_marked[w])
                {
                    _edgeTo[w] = v;
                    _color[w] = !_color[v];
                    Dfs(g, w);
                }

                // if v-w create an odd-length cycle, find it
                else if (_color[w] == _color[v])
                {
                    _isBipartite = false;
                    _cycle = new Collections.Stack<Integer>();
                    _cycle.Push(w);  // don't need this unless you want to include start vertex twice
                    for (var x = v; x != w; x = _edgeTo[x])
                    {
                        _cycle.Push(x);
                    }
                    _cycle.Push(w);
                }
            }
        }
Ejemplo n.º 29
0
        public static void UnitTest(Graph g, string description)
        {
            Console.WriteLine(description);
            Console.WriteLine("-------------------------------------");
            Console.Write(g);

            var euler = new EulerianPath(g);

            Console.Write("Eulerian path:  ");
            if (euler.HasEulerianPath())
            {
                foreach (int v in euler.Path())
                {
                    Console.Write($"{v} ");
                }
                Console.WriteLine();
            }
            else
            {
                Console.WriteLine("none");
            }
            Console.WriteLine();
        }
Ejemplo n.º 30
0
 // returns any non-isolated vertex; -1 if no such vertex
 private static int NonIsolatedVertex(Graph g)
 {
     for (var v = 0; v < g.V; v++)
         if (g.Degree(v) > 0)
             return v;
     return -1;
 }