コード例 #1
0
        /// <summary>
        /// Determines whether the edge-weighted 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(EdgeWeightedDigraph 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 (DirectedEdge e in G.Adj(v))
                {
                    int w = e.To;
                    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));
        }
コード例 #2
0
ファイル: BipartiteX.cs プロジェクト: zzhi/Algs4Net
        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;
                    }
                }
            }
        }
コード例 #3
0
        // is there an augmenting path?
        // an alternating path is a path whose edges belong alternately to the matching and not to the matching
        // an augmenting path is an alternating path that starts and ends at unmatched vertices
        //
        // if so, upon termination edgeTo[] contains a parent-link representation of such a path
        // if not, upon terminatation marked[] specifies the subset of vertices reachable via an alternating
        // path from one side of the bipartition
        //
        // this implementation finds a shortest augmenting path (fewest number of edges), though there
        // is no particular advantage to do so here
        private bool hasAugmentingPath(Graph G)
        {
            marked = new bool[numVertices];

            edgeTo = new int[numVertices];
            for (int v = 0; v < numVertices; v++)
            {
                edgeTo[v] = -1;
            }

            // breadth-first search (starting from all unmatched vertices on one side of bipartition)
            LinkedQueue <int> queue = new LinkedQueue <int>();

            for (int v = 0; v < numVertices; v++)
            {
                if (bipartition.Color(v) && !IsMatched(v))
                {
                    queue.Enqueue(v);
                    marked[v] = true;
                }
            }

            // run BFS, stopping as soon as an alternating path is found
            while (!queue.IsEmpty)
            {
                int v = queue.Dequeue();
                foreach (int w in G.Adj(v))
                {
                    // either (1) forward edge not in matching or (2) backward edge in matching
                    if (isResidualGraphEdge(v, w))
                    {
                        if (!marked[w])
                        {
                            edgeTo[w] = v;
                            marked[w] = true;
                            if (!IsMatched(w))
                            {
                                return(true);
                            }
                            queue.Enqueue(w);
                        }
                    }
                }
            }

            return(false);
        }
コード例 #4
0
ファイル: LinkedQueue.cs プロジェクト: zzhi/Algs4Net
        public static void MainTest(string[] args)
        {
            LinkedQueue <string> q     = new LinkedQueue <string>();
            TextInput            StdIn = new TextInput();

            while (!StdIn.IsEmpty)
            {
                string item = StdIn.ReadString();
                if (!item.Equals("-"))
                {
                    q.Enqueue(item);
                }
                else if (!q.IsEmpty)
                {
                    Console.Write(q.Dequeue() + " ");
                }
            }
            Console.WriteLine("(" + q.Count + " left on queue)");
        }
コード例 #5
0
        /// <summary>
        /// Returns the keys in the BST in level order (for debugging).</summary>
        /// <returns>the keys in the BST in level order traversal</returns>
        ///
        public IEnumerable <Key> LevelOrder()
        {
            LinkedQueue <Key>  keys  = new LinkedQueue <Key>();
            LinkedQueue <Node> queue = new LinkedQueue <Node>();

            queue.Enqueue(root);
            while (!queue.IsEmpty)
            {
                Node x = queue.Dequeue();
                if (x == null)
                {
                    continue;
                }
                keys.Enqueue(x.key);
                queue.Enqueue(x.left);
                queue.Enqueue(x.right);
            }
            return(keys);
        }
コード例 #6
0
        // BFS from single source
        private void bfs(Digraph G, int s)
        {
            LinkedQueue <int> q = new LinkedQueue <int>();

            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);
                    }
                }
            }
        }
コード例 #7
0
        private IEnumerable <DirectedEdge> cycle; // negative cycle (or null if no such cycle)

        /// <summary>Computes a shortest paths tree from <c>s</c> to every other vertex in
        /// the edge-weighted digraph <c>G</c>.</summary>
        /// <param name="G">the acyclic digraph</param>
        /// <param name="s">the source vertex</param>
        /// <exception cref="ArgumentException">unless 0 &lt;= <c>s</c> &lt;= <c>V</c> - 1</exception>
        ///
        public BellmanFordSP(EdgeWeightedDigraph G, int s)
        {
            distTo  = new double[G.V];
            edgeTo  = new DirectedEdge[G.V];
            onQueue = new bool[G.V];
            for (int v = 0; v < G.V; v++)
            {
                distTo[v] = double.PositiveInfinity;
            }
            distTo[s] = 0.0;

            // Bellman-Ford algorithm
            queue = new LinkedQueue <int>();
            queue.Enqueue(s);
            onQueue[s] = true;
            while (!queue.IsEmpty && !HasNegativeCycle)
            {
                int v = queue.Dequeue();
                onQueue[v] = false;
                relax(G, v);
            }

            Debug.Assert(check(G, s));
        }
コード例 #8
0
ファイル: DirectedCycleX.cs プロジェクト: zzhi/Algs4Net
        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());
        }