private Int32 _postCounter;                    // counter for postorder numbering.

        public DepthFirstOrder(Digraph digraph)
        {
            this._pre       = new Int32[digraph.VerticesCount];
            this._post      = new Int32[digraph.VerticesCount];
            this._postOrder = new AST.Queue <Int32>();
            this._preOrder  = new AST.Queue <Int32>();
            this._visited   = new Boolean[digraph.VerticesCount];

            for (int i = 0; i < digraph.VerticesCount; i++)
            {
                if (!this._visited[i])
                {
                    this.DFS(digraph, i);
                }
            }
        }
        public DirectedDepthFirstSearch(Digraph digraph, Int32 sourceVertice)
        {
            if (digraph == null)
            {
                throw new ArgumentNullException(nameof(digraph));
            }

            if (sourceVertice < 0 || sourceVertice > digraph.VerticesCount - 1)
            {
                throw new ArgumentOutOfRangeException(nameof(sourceVertice),
                                                      "Value must be greater or equal to zero and less than " + digraph.VerticesCount);
            }

            this._reachableFromSourceMap = new Boolean[digraph.VerticesCount];

            this.DFS(digraph, sourceVertice);
        }
        private KosarajuSharirSCC(Digraph digraph)
        {
            DepthFirstOrder dfs = new DepthFirstOrder(digraph.Reverse());

            this._visited = new Boolean[digraph.VerticesCount];
            this._ids     = new Int32[digraph.VerticesCount];

            foreach (Int32 vertice in dfs.ReversePost())
            {
                if (!this._visited[vertice])
                {
                    this.DFS(digraph, vertice);

                    this.Count++;
                }
            }
        }
        private void DFS(Digraph graph, Int32 vertice)
        {
            this._visited[vertice] = true;
            this._pre[vertice]     = this._preCounter++;
            this._preOrder.Enqueue(vertice);

            foreach (Int32 adjacent in graph.GetAdjacentVertices(vertice))
            {
                if (!this._visited[adjacent])
                {
                    this.DFS(graph, adjacent);
                }
            }

            this._postOrder.Enqueue(vertice);
            this._post[vertice] = this._postCounter++;
        }
        private CycleChecker(Digraph digraph)
        {
            if (digraph == null)
            {
                throw new ArgumentNullException(nameof(digraph));
            }

            this._visited = new Boolean[digraph.VerticesCount];
            this._onStack = new Boolean[digraph.VerticesCount];
            this._edgeTo  = new Int32[digraph.VerticesCount];

            for (int i = 0; i < digraph.VerticesCount; i++)
            {
                if (!this._visited[i])
                {
                    this.DFS(digraph, i);
                }
            }
        }
        private void DFS(Digraph digraph, Int32 vertice)
        {
            this._onStack[vertice] = true;
            this._visited[vertice] = true;

            foreach (Int32 adjacent in digraph.GetAdjacentVertices(vertice))
            {
                if (this.HasCycle)
                {
                    return;
                }

                // The cycle occurrs when an adjacent vertice is on the stack of
                // "vertices being processed".
                // If vertice A is being processed (onStack) and one of its adjacents
                // points to A again, we have a cycle.

                if (!this._visited[adjacent])
                {
                    this._edgeTo[adjacent] = vertice;

                    this.DFS(digraph, adjacent);
                }
                else if (this._onStack[adjacent])
                {
                    this._cycle = new AST.Stack <Int32>();

                    for (int i = vertice; i != adjacent; i = this._edgeTo[i])
                    {
                        this._cycle.Push(i);
                    }

                    this._cycle.Push(adjacent);
                    this._cycle.Push(vertice);
                }
            }

            // If we fully processed a vertice, it means the vertice is no more on
            // the stack.

            this._onStack[vertice] = false;
        }
        private TopologicalChecker(Digraph digraph)
        {
            CycleChecker checker = CycleChecker.Create(digraph);

            if (!checker.HasCycle)
            {
                DepthFirstOrder dfs = new DepthFirstOrder(digraph);

                this.Order = dfs.ReversePost();

                this._rank = new Int32[digraph.VerticesCount];

                Int32 i = 0;

                foreach (Int32 v in this.Order)
                {
                    this._rank[v] = i++;
                }
            }
        }
        public DirectedDepthFirstSearch(Digraph digraph, IEnumerable <Int32> sources)
        {
            if (digraph == null)
            {
                throw new ArgumentNullException(nameof(digraph));
            }

            if (sources == null)
            {
                throw new ArgumentNullException(nameof(sources));
            }

            this._reachableFromSourceMap = new Boolean[digraph.VerticesCount];

            foreach (Int32 vertice in sources)
            {
                if (!this._reachableFromSourceMap[vertice])
                {
                    this.DFS(digraph, vertice);
                }
            }
        }
Пример #9
0
 public DirectedDfs(Digraph digraph, int startVertex)
 {
     marked = new bool[digraph.Vertices];
     DepthFirstSearch(digraph, startVertex);
 }
 public static KosarajuSharirSCC  Create(Digraph digraph)
 {
     return(new KosarajuSharirSCC(digraph));
 }