Esempio n. 1
0
        private void dfs(Digraph G, int v)
        {
            marked[v] = true;
            low[v]    = pre++;
            int min = low[v];

            stack.Push(v);
            foreach (int w in G.Adj(v))
            {
                if (!marked[w])
                {
                    dfs(G, w);
                }
                if (low[w] < min)
                {
                    min = low[w];
                }
            }
            if (min < low[v])
            {
                low[v] = min;
                return;
            }
            int u;

            do
            {
                u      = stack.Pop();
                id[u]  = count;
                low[u] = G.V;
            } while (u != v);
            count++;
        }
Esempio n. 2
0
 // check that algorithm computes either the topological order or finds a directed cycle
 private void dfs(Digraph G, int v)
 {
     onStack[v] = true;
     marked[v]  = true;
     foreach (int w in G.Adj(v))
     {
         // short circuit if directed cycle found
         if (cycle != null)
         {
             return;
         }
         else if (!marked[w])
         {
             // found new vertex, so recur
             edgeTo[w] = v;
             dfs(G, w);
         }
         else if (onStack[w])
         {
             // trace back directed cycle
             cycle = new LinkedStack <int>();
             for (int x = v; x != w; x = edgeTo[x])
             {
                 cycle.Push(x);
             }
             cycle.Push(w);
             cycle.Push(v);
             Debug.Assert(check());
         }
     }
     onStack[v] = false;
 }
Esempio n. 3
0
        // BFS from multiple sources
        private void bfs(Digraph G, IEnumerable <int> sources)
        {
            LinkedQueue <int> q = new LinkedQueue <int>();

            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])
                    {
                        edgeTo[w] = v;
                        distTo[w] = distTo[v] + 1;
                        marked[w] = true;
                        q.Enqueue(w);
                    }
                }
            }
        }
Esempio n. 4
0
        private void dfs(Digraph G, int v)
        {
            marked[v]   = true;
            preorder[v] = pre++;
            stack1.Push(v);
            stack2.Push(v);
            foreach (int w in G.Adj(v))
            {
                if (!marked[w])
                {
                    dfs(G, w);
                }
                else if (id[w] == -1)
                {
                    while (preorder[stack2.Peek()] > preorder[w])
                    {
                        stack2.Pop();
                    }
                }
            }

            // found strong component containing v
            if (stack2.Peek() == v)
            {
                stack2.Pop();
                int w;
                do
                {
                    w     = stack1.Pop();
                    id[w] = count;
                } while (w != v);
                count++;
            }
        }
Esempio n. 5
0
        private LinkedStack <int> cycle = null; // Eulerian cycle; null if no such cylce

        /// <summary>
        /// Computes an Eulerian cycle in the specified digraph, if one exists.
        /// </summary>
        /// <param name="G">the digraph</param>
        ///
        public DirectedEulerianCycle(Digraph G)
        {
            // must have at least one edge
            if (G.E == 0)
            {
                return;
            }

            // necessary condition: indegree(v) = outdegree(v) for each vertex v
            // (without this check, DFS might return a path instead of a cycle)
            for (int v = 0; v < G.V; v++)
            {
                if (G.Outdegree(v) != G.Indegree(v))
                {
                    return;
                }
            }

            // create local view of adjacency lists, to iterate one vertex at a time
            IEnumerator <int>[] adj = new IEnumerator <int> [G.V];
            for (int v = 0; v < G.V; v++)
            {
                adj[v] = G.Adj(v).GetEnumerator();
            }

            // initialize stack with any non-isolated vertex
            int s = nonIsolatedVertex(G);
            LinkedStack <int> stack = new LinkedStack <int>();

            stack.Push(s);

            // greedily add to putative cycle, depth-first search style
            cycle = new LinkedStack <int>();
            while (!stack.IsEmpty)
            {
                int v = stack.Pop();
                while (adj[v].MoveNext())
                {
                    stack.Push(v);
                    v = adj[v].Current;
                }
                // add vertex with no more leaving edges to cycle
                cycle.Push(v);
            }

            // check if all edges have been used
            // (in case there are two or more vertex-disjoint Eulerian cycles)
            if (cycle.Count != G.E + 1)
            {
                cycle = null;
            }

            Debug.Assert(certifySolution(G));
        }
Esempio n. 6
0
 private void dfs(Digraph G, int v)
 {
     count++;
     marked[v] = true;
     foreach (int w in G.Adj(v))
     {
         if (!marked[w])
         {
             dfs(G, w);
         }
     }
 }
Esempio n. 7
0
 private void dfs(Digraph G, int v)
 {
     marked[v] = true;
     foreach (int w in G.Adj(v))
     {
         if (!marked[w])
         {
             edgeTo[w] = v;
             dfs(G, w);
         }
     }
 }
Esempio n. 8
0
        // certify that digraph is acyclic
        private bool check(Digraph G)
        {
            // digraph is acyclic
            if (HasOrder)
            {
                // check that ranks are a permutation of 0 to V-1
                bool[] found = new bool[G.V];
                for (int i = 0; i < G.V; i++)
                {
                    found[Rank(i)] = true;
                }
                for (int i = 0; i < G.V; i++)
                {
                    if (!found[i])
                    {
                        Console.Error.WriteLine("No vertex with rank " + i);
                        return(false);
                    }
                }

                // check that ranks provide a valid topological order
                for (int v = 0; v < G.V; v++)
                {
                    foreach (int w in G.Adj(v))
                    {
                        if (Rank(v) > Rank(w))
                        {
                            Console.Error.WriteLine("{0}-{1}: rank({2}) = {3}, rank({4}) = {5}\n",
                                                    v, w, v, Rank(v), w, Rank(w));
                            return(false);
                        }
                    }
                }

                // check that order() is consistent with rank()
                int r = 0;
                foreach (int v in Order())
                {
                    if (Rank(v) != r)
                    {
                        Console.Error.WriteLine("Order() and Rank() inconsistent");
                        return(false);
                    }
                    r++;
                }
            }


            return(true);
        }
Esempio n. 9
0
 // run DFS in digraph G from vertex v and compute preorder/postorder
 private void dfs(Digraph G, int v)
 {
     marked[v] = true;
     pre[v]    = preCounter++;
     preorder.Enqueue(v);
     foreach (int w in G.Adj(v))
     {
         if (!marked[w])
         {
             dfs(G, w);
         }
     }
     postorder.Enqueue(v);
     post[v] = postCounter++;
 }
Esempio n. 10
0
        private int[] rank;              // rank[v] = order where vertex v appers in order

        /// <summary>
        /// Determines whether the digraph <c>G</c> has a topological order and, if so,
        /// finds such a topological order.
        /// </summary>
        /// <param name="G">the digraph</param>
        ///
        public TopologicalX(Digraph G)
        {
            // indegrees of remaining vertices
            int[] indegree = new int[G.V];
            for (int v = 0; v < G.V; v++)
            {
                indegree[v] = G.Indegree(v);
            }

            // initialize
            rank  = new int[G.V];
            order = new LinkedQueue <int>();
            int count = 0;

            // initialize queue to contain all vertices with indegree = 0
            LinkedQueue <int> queue = new LinkedQueue <int>();

            for (int v = 0; v < G.V; v++)
            {
                if (indegree[v] == 0)
                {
                    queue.Enqueue(v);
                }
            }

            for (int j = 0; !queue.IsEmpty; j++)
            {
                int v = queue.Dequeue();
                order.Enqueue(v);
                rank[v] = count++;
                foreach (int w in G.Adj(v))
                {
                    indegree[w]--;
                    if (indegree[w] == 0)
                    {
                        queue.Enqueue(w);
                    }
                }
            }

            // there is a directed cycle in subgraph of vertices with indegree >= 1.
            if (count != G.V)
            {
                order = null;
            }

            Debug.Assert(check(G));
        }
Esempio n. 11
0
        /**************************************************************************
        *
        *  The code below is solely for testing correctness of the data type.
        *
        **************************************************************************/

        // 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.
        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
            int deficit = 0;

            for (int 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
            Graph H = new Graph(G.V);

            for (int 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
            int s = nonIsolatedVertex(G);
            BreadthFirstPaths bfs = new BreadthFirstPaths(H, s);

            for (int v = 0; v < G.V; v++)
            {
                if (H.Degree(v) > 0 && !bfs.HasPathTo(v))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 12
0
        /**************************************************************************
        *
        *  The code below is solely for testing correctness of the data type.
        *
        **************************************************************************/

        // Determines whether a digraph has an Eulerian cycle using necessary
        // and sufficient conditions (without computing the cycle itself):
        //    - at least one edge
        //    - indegree(v) = outdegree(v) for every vertex
        //    - the graph is connected, when viewed as an undirected graph
        //      (ignoring isolated vertices)
        private static bool hasEulerianCycle(Digraph G)
        {
            // Condition 0: at least 1 edge
            if (G.E == 0)
            {
                return(false);
            }

            // Condition 1: indegree(v) == outdegree(v) for every vertex
            for (int v = 0; v < G.V; v++)
            {
                if (G.Outdegree(v) != G.Indegree(v))
                {
                    return(false);
                }
            }

            // Condition 2: graph is connected, ignoring isolated vertices
            Graph H = new Graph(G.V);

            for (int v = 0; v < G.V; v++)
            {
                foreach (int w in G.Adj(v))
                {
                    H.AddEdge(v, w);
                }
            }

            // check that all non-isolated vertices are conneted
            int s = nonIsolatedVertex(G);
            BreadthFirstPaths bfs = new BreadthFirstPaths(H, s);

            for (int v = 0; v < G.V; v++)
            {
                if (H.Degree(v) > 0 && !bfs.HasPathTo(v))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 13
0
        public static void MainTest(string[] args)
        {
            string        filename  = args[0];
            string        delimiter = args[1];
            SymbolDigraph sg        = new SymbolDigraph(filename, delimiter);

            Digraph G = sg.G;
            string  t = Console.ReadLine();

            while (t != null)
            {
                if (sg.Contains(t))
                {
                    foreach (int v in G.Adj(sg.Index(t)))
                    {
                        Console.WriteLine("   " + sg.Name(v));
                    }
                }
                t = Console.ReadLine();
            }
        }
Esempio n. 14
0
        private bool[] marked; // marked[v] = is there an s->v path?

        /// <summary>
        /// Computes the vertices reachable from the source vertex <c>s</c> in the
        /// digraph <c>G</c>.</summary>
        /// <param name="G">the digraph</param>
        /// <param name="s">the source vertex</param>
        ///
        public NonrecursiveDirectedDFS(Digraph 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
            IEnumerator <int>[] adj = new IEnumerator <int> [G.V];
            for (int v = 0; v < G.V; v++)
            {
                adj[v] = G.Adj(v).GetEnumerator();
            }

            // depth-first search using an explicit stack
            LinkedStack <int> stack = new LinkedStack <int>();

            marked[s] = true;
            stack.Push(s);
            while (!stack.IsEmpty)
            {
                int v = stack.Peek();
                if (adj[v].MoveNext())
                {
                    int w = adj[v].Current;
                    // Console.Write("check {0}\n", w);
                    if (!marked[w])
                    {
                        // discovered vertex w for the first time
                        marked[w] = true;
                        // edgeTo[w] = v;
                        stack.Push(w);
                        // Console.Write("dfs({0})\n", w);
                    }
                }
                else
                {
                    // Console.Write("{0} done\n", v);
                    stack.Pop();
                }
            }
        }
Esempio n. 15
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");
        }
Esempio n. 16
0
        private LinkedStack <int> cycle; // the directed cycle; null if digraph is acyclic

        /// <summary>
        /// Determines whether the digraph <c>G</c> has a directed cycle and, if so,
        /// finds such a cycle.</summary>
        /// <param name="G">the digraph</param>
        ///
        public DirectedCycleX(Digraph G)
        {
            // indegrees of remaining vertices
            int[] indegree = new int[G.V];
            for (int v = 0; v < G.V; v++)
            {
                indegree[v] = G.Indegree(v);
            }

            // initialize queue to contain all vertices with indegree = 0
            LinkedQueue <int> queue = new LinkedQueue <int>();

            for (int v = 0; v < G.V; v++)
            {
                if (indegree[v] == 0)
                {
                    queue.Enqueue(v);
                }
            }

            for (int j = 0; !queue.IsEmpty; j++)
            {
                int v = queue.Dequeue();
                foreach (int w in G.Adj(v))
                {
                    indegree[w]--;
                    if (indegree[w] == 0)
                    {
                        queue.Enqueue(w);
                    }
                }
            }

            // there is a directed cycle in subgraph of vertices with indegree >= 1.
            int[] edgeTo = new int[G.V];
            int   root   = -1; // any vertex with indegree >= -1

            for (int v = 0; v < G.V; v++)
            {
                if (indegree[v] == 0)
                {
                    continue;
                }
                else
                {
                    root = v;
                }
                foreach (int w in G.Adj(v))
                {
                    if (indegree[w] > 0)
                    {
                        edgeTo[w] = v;
                    }
                }
            }

            if (root != -1)
            {
                // find any vertex on cycle
                bool[] visited = new bool[G.V];
                while (!visited[root])
                {
                    visited[root] = true;
                    root          = edgeTo[root];
                }

                // extract cycle
                cycle = new LinkedStack <int>();
                int v = root;
                do
                {
                    cycle.Push(v);
                    v = edgeTo[v];
                } while (v != root);
                cycle.Push(root);
            }

            Debug.Assert(check());
        }
Esempio n. 17
0
        private LinkedStack <int> path = null; // Eulerian path; null if no suh path

        /// <summary>
        /// Computes an Eulerian path in the specified digraph, if one exists.</summary>
        /// <param name="G">the digraph</param>
        ///
        public DirectedEulerianPath(Digraph G)
        {
            // find vertex from which to start potential Eulerian path:
            // a vertex v with outdegree(v) > indegree(v) if it exits;
            // otherwise a vertex with outdegree(v) > 0
            int deficit = 0;
            int s       = nonIsolatedVertex(G);

            for (int v = 0; v < G.V; v++)
            {
                if (G.Outdegree(v) > G.Indegree(v))
                {
                    deficit += (G.Outdegree(v) - G.Indegree(v));
                    s        = v;
                }
            }

            // digraph can't have an Eulerian path
            // (this condition is needed)
            if (deficit > 1)
            {
                return;
            }

            // special case for digraph 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
            IEnumerator <int>[] adj = new IEnumerator <int> [G.V];
            for (int v = 0; v < G.V; v++)
            {
                adj[v] = G.Adj(v).GetEnumerator();
            }

            // greedily add to cycle, depth-first search style
            LinkedStack <int> stack = new LinkedStack <int>();

            stack.Push(s);
            path = new LinkedStack <int>();
            while (!stack.IsEmpty)
            {
                int v = stack.Pop();
                while (adj[v].MoveNext())
                {
                    stack.Push(v);
                    v = adj[v].Current;
                }
                // push vertex with no more available edges to path
                path.Push(v);
            }

            // check if all edges have been used
            if (path.Count != G.E + 1)
            {
                path = null;
            }

            Debug.Assert(check(G));
        }