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); }
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])); }
/// <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); }
/// <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); }
/// <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); }
public IDiEdge <T> GetOutEdge(IDiGraphVertex <T> targetVertex) { var key = targetVertex as WeightedDiGraphVertex <T, TW>; return(new DiEdge <T, TW>(targetVertex, OutEdges[key])); }
internal DiEdge(IDiGraphVertex <T> target, C weight) { TargetVertex = target; this.weight = weight; }
/// <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)); }