private bool dfs(IDiGraphVertex <T> current,
                         HashSet <T> visited, HashSet <T> visiting)
        {
            visiting.Add(current.Key);

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

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

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

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

            return(false);
        }
Exemple #2
0
            public IDiEdge <T> GetOutEdge(IDiGraphVertex <T> targetVertex)
            {
                if (!vertexIndices.ContainsKey(targetVertex.Key))
                {
                    throw new ArgumentException("vertex is not in this graph.");
                }

                var index = vertexIndices[targetVertex.Key];
                var key   = targetVertex as WeightedDiGraphVertex <T, TW>;

                return(new DiEdge <T, TW>(targetVertex, matrix[vertexIndex, index]));
            }
Exemple #3
0
        /// <summary>
        /// Do a depth first search.
        /// </summary>
        private void dfs(IDiGraphVertex <T> vertex,
                         HashSet <T> visited, Stack <T> pathStack)
        {
            visited.Add(vertex.Key);

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

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

            foreach (var edge in currentVertex.OutEdges)
            {
                if (!visited.Contains(edge.TargetVertexKey))
                {
                    kosarajuStep2(edge.TargetVertex, visited, finishStack, result);
                }
            }

            return(result);
        }
Exemple #5
0
        /// <summary>
        /// Just do a DFS keeping track on finish Stack of Vertices.
        /// </summary>
        private void kosarajuStep1(IDiGraphVertex <T> currentVertex,
                                   HashSet <T> visited,
                                   Stack <T> finishStack)
        {
            visited.Add(currentVertex.Key);

            foreach (var edge in currentVertex.OutEdges)
            {
                if (!visited.Contains(edge.TargetVertexKey))
                {
                    kosarajuStep1(edge.TargetVertex, visited, finishStack);
                }
            }

            //finished visiting, so add to stack
            finishStack.Push(currentVertex.Key);
        }
Exemple #6
0
        public IDiEdge <T> GetOutEdge(IDiGraphVertex <T> targetVertex)
        {
            var key = targetVertex as WeightedDiGraphVertex <T, TW>;

            return(new DiEdge <T, TW>(targetVertex, OutEdges[key]));
        }
Exemple #7
0
 internal DiEdge(IDiGraphVertex <T> target, C weight)
 {
     TargetVertex = target;
     this.weight  = weight;
 }
Exemple #8
0
        /// <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>
        private void DFS(IDiGraphVertex <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.Key, discoveryTime);
            lowTimeMap.Add(currentVertex.Key, discoveryTime);
            pathStack.Push(currentVertex.Key);
            pathStackMap.Add(currentVertex.Key);

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

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

            //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.Key] != discoveryTimeMap[currentVertex.Key])
            {
                return;
            }

            var strongConnected = new List <T>();

            while (!pathStack.Peek().Equals(currentVertex.Key))
            {
                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);
        }
 public IDiEdge <T> GetOutEdge(IDiGraphVertex <T> targetVertex)
 {
     return(new DiEdge <T, int>(targetVertex, 1));
 }