Ejemplo n.º 1
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++;
            }
        }
Ejemplo n.º 2
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();
                }
            }
        }
Ejemplo n.º 3
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();
                }
            }
        }
Ejemplo n.º 4
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());
        }
Ejemplo n.º 5
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));
        }