Exemple #1
0
        private bool dfs(DiGraphVertex <T> current,
                         HashSet <T> visited, HashSet <T> visiting)
        {
            visiting.Add(current.Value);

            foreach (var edge in current.OutEdges)
            {
                //if we encountered a visiting vertex again
                //then their is a cycle
                if (visiting.Contains(edge.Value))
                {
                    return(true);
                }

                if (visited.Contains(edge.Value))
                {
                    continue;
                }

                if (dfs(edge, visited, visiting))
                {
                    return(true);
                }
            }

            visiting.Remove(current.Value);
            visited.Add(current.Value);

            return(false);
        }
        /// <summary>
        /// Do a depth first search to find Strongly Connected by keeping track of
        /// discovery nodes and checking for back edges using low/discovery time maps
        /// </summary>
        /// <param name="currentVertex"></param>
        /// <param name="result"></param>
        /// <param name="discovery"></param>
        /// <param name="discoveryTimeMap"></param>
        /// <param name="lowTimeMap"></param>
        /// <param name="parent"></param>
        /// <param name="discoveryTime"></param>
        /// <returns></returns>
        private void DFS(DiGraphVertex <T> currentVertex,
                         List <List <T> > result,
                         Dictionary <T, int> discoveryTimeMap, Dictionary <T, int> lowTimeMap,
                         Stack <T> pathStack,
                         HashSet <T> pathStackMap, ref int discoveryTime)
        {
            discoveryTimeMap.Add(currentVertex.Value, discoveryTime);
            lowTimeMap.Add(currentVertex.Value, discoveryTime);
            pathStack.Push(currentVertex.Value);
            pathStackMap.Add(currentVertex.Value);

            foreach (var edge in currentVertex.OutEdges)
            {
                if (!discoveryTimeMap.ContainsKey(edge.Value))
                {
                    discoveryTime++;
                    DFS(edge, result, discoveryTimeMap, lowTimeMap,
                        pathStack, pathStackMap, ref discoveryTime);

                    //propogate lowTime index of neighbour so that ancestors can see it in DFS
                    lowTimeMap[currentVertex.Value] =
                        Math.Min(lowTimeMap[currentVertex.Value], lowTimeMap[edge.Value]);
                }
                else
                {
                    //ignore cross edges
                    //even if edge vertex was already visisted
                    //update this so that ancestors can see it
                    if (pathStackMap.Contains(edge.Value))
                    {
                        lowTimeMap[currentVertex.Value] =
                            Math.Min(lowTimeMap[currentVertex.Value],
                                     discoveryTimeMap[edge.Value]);
                    }
                }
            }

            //if low is high this means we reached head of the DFS tree with strong connectivity
            //now print items in the stack
            if (lowTimeMap[currentVertex.Value] == discoveryTimeMap[currentVertex.Value])
            {
                var strongConnected = new List <T>();
                while (!pathStack.Peek().Equals(currentVertex.Value))
                {
                    var vertex = pathStack.Pop();
                    strongConnected.Add(vertex);
                    pathStackMap.Remove(vertex);
                }

                //add current vertex
                var finalVertex = pathStack.Pop();
                strongConnected.Add(finalVertex);
                pathStackMap.Remove(finalVertex);

                result.Add(strongConnected);
            }
        }
        /// <summary>
        /// Do a depth first search
        /// </summary>
        /// <param name="vertex"></param>
        /// <param name="visited"></param>
        /// <param name="pathStack"></param>
        private void dfs(DiGraphVertex <T> vertex,
                         HashSet <T> visited, Stack <T> pathStack)
        {
            visited.Add(vertex.Value);

            foreach (var edge in vertex.OutEdges)
            {
                if (!visited.Contains(edge.Value))
                {
                    dfs(edge, visited, pathStack);
                }
            }

            //add vertex to stack after all edges are visited
            pathStack.Push(vertex.Value);
        }
Exemple #4
0
        /// <summary>
        /// In step two we just add all reachable nodes to result (connected componant)
        /// </summary>
        /// <param name="currentVertex"></param>
        /// <param name="visited"></param>
        /// <param name="finishStack"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private List <T> KosarajuStep2(DiGraphVertex <T> currentVertex,
                                       HashSet <T> visited, Stack <T> finishStack,
                                       List <T> result)
        {
            visited.Add(currentVertex.Value);
            result.Add(currentVertex.Value);

            foreach (var edge in currentVertex.OutEdges)
            {
                if (!visited.Contains(edge.Value))
                {
                    KosarajuStep2(edge, visited, finishStack, result);
                }
            }

            return(result);
        }
Exemple #5
0
        /// <summary>
        /// Just do a DFS keeping track on finish Stack of Vertices
        /// </summary>
        /// <param name="currentVertex"></param>
        /// <param name="visited"></param>
        /// <param name="finishStack"></param>
        private void KosarajuStep1(DiGraphVertex <T> currentVertex,
                                   HashSet <T> visited,
                                   Stack <T> finishStack)
        {
            visited.Add(currentVertex.Value);

            foreach (var edge in currentVertex.OutEdges)
            {
                if (!visited.Contains(edge.Value))
                {
                    KosarajuStep1(edge, visited, finishStack);
                }
            }

            //finished visiting, so add to stack
            finishStack.Push(currentVertex.Value);
        }