Example #1
0
        /// <summary>
        /// Scans the specified graph, using recursion, and produces SCC results.
        /// </summary>
        /// <param name="graph">The graph to search.</param>
        /// <param name="vertex">The current vertex to scan and connect.</param>
        /// <param name="weigher">The optional weigher to use.</param>
        /// <param name="result">The graph search result.</param>
        /// <returns>Augmentation vertex data for the current vertex.</returns>
        private VertexData Connect(IGraph <V, E> graph, V vertex, IEdgeWeigher <V, E> weigher, SccResult result)
        {
            VertexData data = result.AddData(vertex);

            // Scan through all egress edges of the current vertex.
            foreach (E edge in graph.GetEdgesFrom(vertex))
            {
                V nextVertex = edge.Dst;

                // If edge is not viable, skip it.
                if (weigher != null && !weigher.GetWeight(edge).IsViable)
                {
                    continue;
                }

                // Attempt to get the augmentation vertex data for the next vertex.
                VertexData nextData = result.GetData(nextVertex);
                if (nextData is null)
                {
                    // Next vertex has not been visited yet, so do this now.
                    nextData     = Connect(graph, nextVertex, weigher, result);
                    data.LowLink = Math.Min(data.LowLink, nextData.LowLink);
                }
                else if (result.Visited(nextData))
                {
                    // Next vertex has been visited, which means
                    // it is in the same cluster as the current vertex.
                    data.LowLink = Math.Min(data.LowLink, nextData.Index);
                }
            }

            if (data.LowLink == data.Index)
            {
                result.AddCluster(data);
            }
            return(data);
        }
Example #2
0
 /// <summary>
 /// Determines whether the given vertex has been visited.
 /// </summary>
 /// <param name="data">The vertex to check.</param>
 /// <returns>True if the vertex has been visited, otherwise false.</returns>
 internal bool Visited(VertexData data) => visited.Contains(data);