Beispiel #1
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 LinkedStack <int>();
                    cycle.Push(w); // don't need this unless you want to include start vertex twice
                    for (int x = v; x != w; x = edgeTo[x])
                    {
                        cycle.Push(x);
                    }
                    cycle.Push(w);
                }
            }
        }
Beispiel #2
0
        // does this graph have two parallel edges?
        // side effect: initialize cycle to be two parallel edges
        private bool hasParallelEdges(Graph G)
        {
            marked = new bool[G.V];

            for (int v = 0; v < G.V; v++)
            {
                // check for parallel edges incident to v
                foreach (int w in G.Adj(v))
                {
                    if (marked[w])
                    {
                        cycle = new LinkedStack <int>();
                        cycle.Push(v);
                        cycle.Push(w);
                        cycle.Push(v);
                        return(true);
                    }
                    marked[w] = true;
                }

                // reset so marked[v] = false for all v
                foreach (int w in G.Adj(v))
                {
                    marked[w] = false;
                }
            }
            return(false);
        }
Beispiel #3
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;
 }
Beispiel #4
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 LinkedStack <int>();
                    for (int x = v; x != w; x = edgeTo[x])
                    {
                        cycle.Push(x);
                    }
                    cycle.Push(w);
                    cycle.Push(v);
                }
            }
        }
Beispiel #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));
        }
Beispiel #6
0
        private void bfs(Graph G, int s)
        {
            LinkedQueue <int> q = new LinkedQueue <int>();

            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 LinkedQueue <int>();
                        LinkedStack <int> stack = new LinkedStack <int>();
                        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;
                    }
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Returns a path between the source vertex <c>s</c> and vertex <c>v</c>, or
        /// <c>null</c> if no such path.</summary>
        /// <param name="v">the vertex</param>
        /// <returns>the sequence of vertices on a path between the source vertex
        /// <c>s</c> and vertex <c>v</c>, as an IEnumerable</returns>
        ///
        public IEnumerable <int> PathTo(int v)
        {
            if (!HasPathTo(v))
            {
                return(null);
            }
            LinkedStack <int> path = new LinkedStack <int>();

            for (int x = v; x != s; x = edgeTo[x])
            {
                path.Push(x);
            }
            path.Push(s);
            return(path);
        }
Beispiel #8
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++;
        }
Beispiel #9
0
        public static void MainTest(string[] args)
        {
            int M = int.Parse(args[0]);
            MinPQ <Transaction> pq = new MinPQ <Transaction>(M + 1);

            TextInput StdIn = new TextInput();

            while (!StdIn.IsEmpty)
            {
                // Create an entry from the next line and put on the PQ.
                string      line        = StdIn.ReadLine();
                Transaction transaction = new Transaction(line);
                pq.Insert(transaction);

                // remove minimum if M+1 entries on the PQ
                if (pq.Count > M)
                {
                    pq.DelMin();
                }
            } // top M entries are on the PQ

            // print entries on PQ in reverse order
            LinkedStack <Transaction> stack = new LinkedStack <Transaction>();

            foreach (Transaction transaction in pq)
            {
                stack.Push(transaction);
            }
            foreach (Transaction transaction in stack)
            {
                Console.WriteLine(transaction);
            }
        }
Beispiel #10
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++;
            }
        }
Beispiel #11
0
        // additional test
        static void TopInts()
        {
            int[]       allInts = { 12, 11, 8, 7, 9, 5, 4, 3, 2, 29, 23, 1, 24, 30, 9, 4, 88, 5, 100, 29, 23, 5, 99, 87, 22, 111 };
            MinPQ <int> pq0     = new MinPQ <int>(allInts);
            int         M       = allInts.Length / 3;
            MinPQ <int> pq      = new MinPQ <int>(M + 1);

            Console.WriteLine("Top {0} is ", M);
            foreach (var n in allInts)
            {
                pq.Insert(n);
                Console.WriteLine("Min is {0}", pq.Min);
                // remove minimum if M+1 entries on the PQ
                if (pq.Count > M)
                {
                    pq.DelMin();
                }
            }
            // print entries on PQ in reverse order
            LinkedStack <int> stack = new LinkedStack <int>();

            foreach (int n in pq)
            {
                stack.Push(n);
            }
            foreach (int n in stack)
            {
                Console.WriteLine(n);
            }
            Console.WriteLine("These are the top elements");
        }
Beispiel #12
0
 // does this graph have a self loop?
 // side effect: initialize cycle to be self loop
 private bool hasSelfLoop(Graph G)
 {
     for (int v = 0; v < G.V; v++)
     {
         foreach (int w in G.Adj(v))
         {
             if (v == w)
             {
                 cycle = new LinkedStack <int>();
                 cycle.Push(v);
                 cycle.Push(v);
                 return(true);
             }
         }
     }
     return(false);
 }
Beispiel #13
0
        private readonly int s; // source vertex

        /// <summary>
        /// Computes the vertices connected to the source vertex <c>s</c> in the graph <c>G</c>.</summary>
        /// <param name="G">the graph</param>
        /// <param name="s">the source vertex</param>
        ///
        public NonrecursiveDFS(Graph G, int s)
        {
            this.s = s;
            marked = new bool[G.V];
            edgeTo = new int[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);
            //Console.Write("Visiting ({0})\n", s);
            while (!stack.IsEmpty)
            {
                int v = stack.Peek();
                if (adj[v].MoveNext())
                {
                    int w = adj[v].Current;
                    //Console.Write("Approaching {0}\n", w);
                    if (!marked[w])
                    {
                        // discovered vertex w for the first time
                        marked[w] = true;
                        edgeTo[w] = v;
                        stack.Push(w);
                        //Console.Write("Visiting ({0})\n", w);
                    }
                    //else
                    //  Console.Write("Visited {0}\n", w);
                }
                else
                {
                    //Console.Write("Returning from {0}\n", stack.Peek());
                    stack.Pop();
                }
            }
        }
Beispiel #14
0
        /// <summary>
        /// Returns the extreme points on the convex hull in counterclockwise order.</summary>
        /// <returns>the extreme points on the convex hull in counterclockwise order</returns>
        ///
        public IEnumerable <Point2D> Hull()
        {
            LinkedStack <Point2D> s = new LinkedStack <Point2D>();

            foreach (Point2D p in hull)
            {
                s.Push(p);
            }
            return(s);
        }
Beispiel #15
0
        /// <summary>
        /// Returns the vertices in reverse postorder.</summary>
        /// <returns>the vertices in reverse postorder, as an iterable of vertices</returns>
        ///
        public IEnumerable <int> ReversePost()
        {
            LinkedStack <int> reverse = new LinkedStack <int>();

            foreach (int v in postorder)
            {
                reverse.Push(v);
            }
            return(reverse);
        }
        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();
                }
            }
        }
Beispiel #17
0
        private int M;         // number of characters in regular expression

        /// <summary>Initializes the NFA from the specified regular expression.</summary>
        /// <param name="regexp">the regular expression</param>
        /// <exception cref="ArgumentException">if the regular expression is invalid</exception>
        ///
        public NFA(string regexp)
        {
            this.regexp = regexp;
            M           = regexp.Length;
            LinkedStack <int> ops = new LinkedStack <int>();

            G = new Digraph(M + 1);
            for (int i = 0; i < M; i++)
            {
                int lp = i;
                if (regexp[i] == '(' || regexp[i] == '|')
                {
                    ops.Push(i);
                }
                else if (regexp[i] == ')')
                {
                    int or = ops.Pop();

                    // 2-way or operator
                    if (regexp[or] == '|')
                    {
                        lp = ops.Pop();
                        G.AddEdge(lp, or + 1);
                        G.AddEdge(or, i);
                    }
                    else if (regexp[or] == '(')
                    {
                        lp = or;
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }

                // closure operator (uses 1-character lookahead)
                if (i < M - 1 && regexp[i + 1] == '*')
                {
                    G.AddEdge(lp, i + 1);
                    G.AddEdge(i + 1, lp);
                }
                if (regexp[i] == '(' || regexp[i] == '*' || regexp[i] == ')')
                {
                    G.AddEdge(i, i + 1);
                }
            }
            if (ops.Count != 0)
            {
                throw new ArgumentException("Invalid regular expression");
            }
        }
Beispiel #18
0
        /// <summary>
        /// Returns a longest path from the source vertex <c>s</c> to vertex <c>v</c>.</summary>
        /// <param name="v">the destination vertex</param>
        /// <returns>a longest path from the source vertex <c>s</c> to vertex <c>v</c></returns>
        ///   as an iterable of edges, and <c>null</c> if no such path
        ///
        public IEnumerable <DirectedEdge> PathTo(int v)
        {
            if (!HasPathTo(v))
            {
                return(null);
            }
            LinkedStack <DirectedEdge> path = new LinkedStack <DirectedEdge>();

            for (DirectedEdge e = edgeTo[v]; e != null; e = edgeTo[e.From])
            {
                path.Push(e);
            }
            return(path);
        }
        // check that algorithm computes either the topological order or finds a directed cycle
        private void dfs(EdgeWeightedDigraph G, int v)
        {
            onStack[v] = true;
            marked[v]  = true;
            foreach (DirectedEdge e in G.Adj(v))
            {
                int w = e.To;

                // short circuit if directed cycle found
                if (cycle != null)
                {
                    return;
                }
                else if (!marked[w])
                {
                    //found new vertex, so recur
                    edgeTo[w] = e;
                    dfs(G, w);
                }
                else if (onStack[w])
                {
                    // trace back directed cycle
                    cycle = new LinkedStack <DirectedEdge>();
                    DirectedEdge eTemp = e;
                    while (eTemp.From != w)
                    {
                        cycle.Push(eTemp);
                        eTemp = edgeTo[eTemp.From];
                    }
                    cycle.Push(eTemp);
                    return;
                }
            }

            onStack[v] = false;
        }
Beispiel #20
0
        /// <summary>
        /// Returns a shortest path between the source vertex <c>s</c> and vertex <c>v</c>.</summary>
        /// <param name="v">the destination vertex</param>
        /// <returns>a shortest path between the source vertex <c>s</c> and vertex <c>v</c>;
        /// <c>null</c> if no such path</returns>
        ///
        public IEnumerable <Edge> PathTo(int v)
        {
            if (!HasPathTo(v))
            {
                return(null);
            }
            LinkedStack <Edge> path = new LinkedStack <Edge>();
            int x = v;

            for (Edge e = edgeTo[v]; e != null; e = edgeTo[x])
            {
                path.Push(e);
                x = e.Other(x);
            }
            return(path);
        }
Beispiel #21
0
 /// <summary>
 /// Initializes a new graph that is a deep copy of <c>G</c>.</summary>
 /// <param name="G">the graph to copy</param>
 ///
 public Graph(Graph G) : this(G.V)
 {
     numEdges = G.E;
     for (int v = 0; v < G.V; v++)
     {
         // reverse so that adjacency list is in same order as original
         LinkedStack <int> reverse = new LinkedStack <int>();
         foreach (int w in G.adj[v])
         {
             reverse.Push(w);
         }
         foreach (int w in reverse)
         {
             adj[v].Add(w);
         }
     }
 }
Beispiel #22
0
        /// <summary>
        /// Returns a shortest path from vertex <c>s</c> to vertex <c>t</c>.</summary>
        /// <param name="s">the source vertex</param>
        /// <param name="t">the destination vertex</param>
        /// <returns>a shortest path from vertex <c>s</c> to vertex <c>t</c>
        /// as an iterable of edges, and <c>null</c> if no such path</returns>
        /// <exception cref="InvalidOperationException">if there is a negative cost cycle</exception>
        ///
        public IEnumerable <DirectedEdge> Path(int s, int t)
        {
            if (HasNegativeCycle)
            {
                throw new InvalidOperationException("Negative cost cycle exists");
            }
            if (!HasPath(s, t))
            {
                return(null);
            }
            LinkedStack <DirectedEdge> path = new LinkedStack <DirectedEdge>();

            for (DirectedEdge e = edgeTo[s, t]; e != null; e = edgeTo[s, e.From])
            {
                path.Push(e);
            }
            return(path);
        }
Beispiel #23
0
        public static void MainTest(string[] args)
        {
            LinkedStack <string> s = new LinkedStack <string>();

            TextInput StdIn = new TextInput();

            while (!StdIn.IsEmpty)
            {
                string item = StdIn.ReadString();
                if (!item.Equals("-"))
                {
                    s.Push(item);
                }
                else if (!s.IsEmpty)
                {
                    Console.Write(s.Pop() + " ");
                }
            }
            Console.WriteLine("(" + s.Count + " left on stack)");
        }
Beispiel #24
0
        /// <summary>
        /// Computes the convex hull of the specified array of points.
        /// </summary>
        /// <param name="pts">the array of points</param>
        /// <exception cref="NullReferenceException">if <c>points</c> is <c>null</c> or if any
        /// entry in <c>points[]</c> is <c>null</c></exception>
        ///
        public GrahamScan(Point2D[] pts)
        {
            // defensive copy
            int N = pts.Length;

            Point2D[] points = new Point2D[N];
            for (int i = 0; i < N; i++)
            {
                points[i] = pts[i];
            }

            // preprocess so that points[0] has lowest y-coordinate; break ties by x-coordinate
            // points[0] is an extreme point of the convex hull
            // (alternatively, could do easily in linear time)
            Array.Sort(points);

            // sort by polar angle with respect to base point points[0],
            // breaking ties by distance to points[0]
            Array.Sort(points, 1, N - 1, points[0].GetPolarOrder());

            hull.Push(points[0]); // p[0] is first extreme point

            // find index k1 of first point not equal to points[0]
            int k1;

            for (k1 = 1; k1 < N; k1++)
            {
                if (!points[0].Equals(points[k1]))
                {
                    break;
                }
            }
            if (k1 == N)
            {
                return;           // all points equal
            }
            // find index k2 of first point not collinear with points[0] and points[k1]
            int k2;

            for (k2 = k1 + 1; k2 < N; k2++)
            {
                if (Point2D.Ccw(points[0], points[k1], points[k2]) != 0)
                {
                    break;
                }
            }
            hull.Push(points[k2 - 1]); // points[k2-1] is second extreme point

            // Graham scan; note that points[N-1] is extreme point different from points[0]
            for (int i = k2; i < N; i++)
            {
                Point2D top = hull.Pop();
                while (Point2D.Ccw(hull.Peek(), top, points[i]) <= 0)
                {
                    top = hull.Pop();
                }
                hull.Push(top);
                hull.Push(points[i]);
            }

            Debug.Assert(isConvex());
        }
Beispiel #25
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));
        }
Beispiel #26
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());
        }
Beispiel #27
0
        private int[] distTo;            // distTo[v] = number of edges on shortest path to v

        /// <summary>
        /// Determines a maximum matching (and a minimum vertex cover)
        /// in a bipartite graph.</summary>
        /// <param name="G">the bipartite graph</param>
        /// <exception cref="ArgumentException">if <c>G</c> is not bipartite</exception>
        ///
        public HopcroftKarp(Graph G)
        {
            bipartition = new BipartiteX(G);
            if (!bipartition.IsBipartite)
            {
                throw new ArgumentException("graph is not bipartite");
            }

            // initialize empty matching
            this.V = G.V;
            mate   = new int[V];
            for (int v = 0; v < V; v++)
            {
                mate[v] = UNMATCHED;
            }

            // the call to hasAugmentingPath() provides enough info to reconstruct level graph
            while (hasAugmentingPath(G))
            {
                // 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();
                }

                // for each unmatched vertex s on one side of bipartition
                for (int s = 0; s < V; s++)
                {
                    if (IsMatched(s) || !bipartition.Color(s))
                    {
                        continue;                                // or use distTo[s] == 0
                    }
                    // find augmenting path from s using nonrecursive DFS
                    LinkedStack <int> path = new LinkedStack <int>();
                    path.Push(s);
                    while (!path.IsEmpty)
                    {
                        int v = path.Peek();

                        // retreat, no more edges in level graph leaving v
                        if (!adj[v].MoveNext())
                        {
                            path.Pop();
                        }

                        // advance
                        else
                        {
                            // process edge v-w only if it is an edge in level graph
                            int w = adj[v].Current;
                            if (!isLevelGraphEdge(v, w))
                            {
                                continue;
                            }

                            // add w to augmenting path
                            path.Push(w);

                            // augmenting path found: update the matching
                            if (!IsMatched(w))
                            {
                                // Console.WriteLine("augmenting path: " + toString(path));

                                while (!path.IsEmpty)
                                {
                                    int x = path.Pop();
                                    int y = path.Pop();
                                    mate[x] = y;
                                    mate[y] = x;
                                }
                                cardinality++;
                            }
                        }
                    }
                }
            }

            // also find a min vertex cover
            inMinVertexCover = new bool[V];
            for (int v = 0; v < V; v++)
            {
                if (bipartition.Color(v) && !marked[v])
                {
                    inMinVertexCover[v] = true;
                }
                if (!bipartition.Color(v) && marked[v])
                {
                    inMinVertexCover[v] = true;
                }
            }

            Debug.Assert(certifySolution(G));
        }
Beispiel #28
0
        /// <summary>
        /// Computes an Eulerian path in the specified graph, if one exists.</summary>
        /// <param name="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
            int oddDegreeVertices = 0;
            int s = nonIsolatedVertex(G);

            for (int 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
            LinkedQueue <Edge>[] adj = new LinkedQueue <Edge> [G.V];
            for (int v = 0; v < G.V; v++)
            {
                adj[v] = new LinkedQueue <Edge>();
            }

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

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

            stack.Push(s);

            // greedily search through edges in iterative DFS style
            path = new LinkedStack <int>();
            while (!stack.IsEmpty)
            {
                int v = stack.Pop();
                while (!adj[v].IsEmpty)
                {
                    Edge 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.Count != G.E + 1)
            {
                path = null;
            }

            Debug.Assert(certifySolution(G));
        }
Beispiel #29
0
        /// <summary>
        /// Computes an Eulerian cycle in the specified graph, if one exists.</summary>
        /// <param name="G">the graph</param>
        ///
        public EulerianCycle(Graph G)
        {
            // must have at least one edge
            if (G.E == 0)
            {
                return;
            }

            // necessary condition: all vertices have even degree
            // (this test is needed or it might find an Eulerian path instead of cycle)
            for (int v = 0; v < G.V; v++)
            {
                if (G.Degree(v) % 2 != 0)
                {
                    return;
                }
            }

            // 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
            LinkedQueue <Edge>[] adj = new LinkedQueue <Edge> [G.V];
            for (int v = 0; v < G.V; v++)
            {
                adj[v] = new LinkedQueue <Edge>();
            }

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

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

            stack.Push(s);

            // greedily search through edges in iterative DFS style
            cycle = new LinkedStack <int>();
            while (!stack.IsEmpty)
            {
                int v = stack.Pop();
                while (!adj[v].IsEmpty)
                {
                    Edge 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 cycle
                cycle.Push(v);
            }

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

            Debug.Assert(certifySolution(G));
        }