public static IEnumerable <int> TopologicalSorting(GraphAdjacentLists <int> graph) { if (graph.DirectedGraph == GraphAdjacentLists <int> .DirectedGraphEnum.Undirected) { return(Enumerable.Empty <int>()); } var traversedNodesStack = new Stack <int>(); var traversedNodes = new List <int>(); foreach (var node in graph.Vertices) { traversedNodesStack.Clear(); foreach (var traversedNode in DFSGraphNodesRecursive(graph, node)) { traversedNodesStack.Push(traversedNode.Item1); } if (traversedNodesStack.Count() == graph.Vertices.Count()) { break; } } foreach (var traversedNode in traversedNodesStack) { traversedNodes.Add(traversedNode); } return(traversedNodes); }
private static IEnumerable <int> TraverseGraphRecursive(GraphAdjacentLists <int> graph, Queue <int> toBeTraversedNodes, HashSet <int> traversedNodes) { if (toBeTraversedNodes.Empty()) { return(Enumerable.Empty <int>()); } var returnValue = new List <int>(); var newToBeTraversedNodes = new Queue <int>(); while (!toBeTraversedNodes.Empty()) { var currentNode = toBeTraversedNodes.Dequeue(); if (traversedNodes.Contains(currentNode)) { continue; } traversedNodes.Add(currentNode); returnValue.Add(currentNode); foreach (var node in graph.GetAdjacentVertices(currentNode)) { newToBeTraversedNodes.Enqueue(node); } } return(returnValue.Concat(TraverseGraphRecursive(graph, newToBeTraversedNodes, traversedNodes))); }
public static IEnumerable <GraphComponent <int> > BFSGraphIterative(GraphAdjacentLists <int> graph, int startNode) { var discoveredNodesQueue = new Queue <Tuple <int?, int> >(); var discoveredNodes = new HashSet <int>(); var processedNodesQueue = new Queue <int>(); var processedNodes = new HashSet <int>(); discoveredNodesQueue.Enqueue(new Tuple <int?, int>(null, startNode)); discoveredNodes.Add(startNode); while (discoveredNodesQueue.Empty()) { var currentNodeInfo = discoveredNodesQueue.Dequeue(); var currentNodeParent = currentNodeInfo.Item1; var currentNode = currentNodeInfo.Item2; yield return(new GraphComponent <int> { Type = GraphComponent <int> .TypeEnum.Node, ParentNode = currentNodeParent, NodeValue = currentNode, NodeIsProcessed = false }); foreach (var node in graph.GetAdjacentVertices(currentNode)) { if (!processedNodes.Contains(node) || graph.DirectedGraph == GraphAdjacentLists <int> .DirectedGraphEnum.Directed) { yield return(new GraphComponent <int> { Type = GraphComponent <int> .TypeEnum.Edge, EdgeStart = currentNode, EdgeEnd = node }); } if (!discoveredNodes.Contains(node)) { discoveredNodesQueue.Enqueue(new Tuple <int?, int>(currentNode, node)); } } processedNodes.Add(currentNode); processedNodesQueue.Enqueue(currentNode); yield return(new GraphComponent <int> { Type = GraphComponent <int> .TypeEnum.Node, NodeValue = currentNode, NodeIsProcessed = true }); } }
public static IEnumerable <int> TraverseGraphRecursive(GraphAdjacentLists <int> graph) { if (!graph.FirstVertex.HasValue) { return(Enumerable.Empty <int>()); } var toBeTraversedNodes = new Queue <int>(); toBeTraversedNodes.Enqueue(graph.FirstVertex.Value); return(TraverseGraphRecursive(graph, toBeTraversedNodes, new HashSet <int>())); }
public static IEnumerable <Tuple <int, int, int> > DFSGraphNodesRecursive(GraphAdjacentLists <int> graph, int startNode, HashSet <int> discoveredNodes = null, HashSet <int> processedNodes = null, int?timer = null) { if (!graph.HasVertex(startNode)) { yield break; } var currentNode = startNode; if (discoveredNodes == null) { discoveredNodes = new HashSet <int>(); } if (processedNodes == null) { processedNodes = new HashSet <int>(); } if (!timer.HasValue) { timer = 0; } discoveredNodes.Add(currentNode); var entryTime = timer.Value; ++timer; foreach (var node in graph.GetAdjacentVertices(currentNode)) { if (discoveredNodes.Contains(node)) { continue; } foreach (var subNode in DFSGraphNodesRecursive(graph, node, discoveredNodes, processedNodes, timer)) { yield return(subNode); } } processedNodes.Add(currentNode); ++timer; var exitTime = timer.Value; yield return(new Tuple <int, int, int>(startNode, entryTime, exitTime)); }
public static IEnumerable <int> TraverseGraphIterative(GraphAdjacentLists <int> graph, int?vertex = null) { if (!graph.FirstVertex.HasValue) { return(Enumerable.Empty <int>()); } if (!vertex.HasValue) { vertex = graph.FirstVertex; } var returnValue = new List <int>(); var traversedNodes = new HashSet <int>(); var toBeTraversedNodes = new Queue <int>(); toBeTraversedNodes.Enqueue(vertex.Value); while (!toBeTraversedNodes.Empty()) { var currentNode = toBeTraversedNodes.Dequeue(); if (traversedNodes.Contains(currentNode)) { continue; } traversedNodes.Add(currentNode); returnValue.Add(currentNode); foreach (var node in graph.GetAdjacentVertices(currentNode)) { toBeTraversedNodes.Enqueue(node); } } return(returnValue); }
public static int GetConnectedComponentsCount(GraphAdjacentLists <int> graph) { var componentId = 0; var vertexToComponentTable = new Dictionary <int, int>(); foreach (var vertex in graph.Vertices) { if (vertexToComponentTable.ContainsKey(vertex)) { continue; } ++componentId; var traversedNodes = TraverseGraphIterative(graph, vertex); foreach (var traversedNode in traversedNodes) { if (!vertexToComponentTable.ContainsKey(traversedNode)) { vertexToComponentTable[traversedNode] = componentId; } } } return(componentId); }
public static (IEnumerable <int>, IEnumerable <string>) TraverseGraphWithEdgesIterative(GraphAdjacentLists <int> graph) { if (!graph.FirstVertex.HasValue) { return(Enumerable.Empty <int>(), Enumerable.Empty <string>()); } var processedNodes = new HashSet <int>(); var traversedEdges = new HashSet <Tuple <int, int> >(); var toBeTraversedNodes = new Queue <int>(); toBeTraversedNodes.Enqueue(graph.FirstVertex.Value); while (!toBeTraversedNodes.Empty()) { var currentNode = toBeTraversedNodes.Dequeue(); processedNodes.Add(currentNode); foreach (var node in graph.GetAdjacentVertices(currentNode)) { if (graph.DirectedGraph == GraphAdjacentLists <int> .DirectedGraphEnum.Directed || !processedNodes.Contains(node)) { traversedEdges.Add(new Tuple <int, int>(currentNode, node)); } if (!processedNodes.Contains(node)) { toBeTraversedNodes.Enqueue(node); } } } return(processedNodes, traversedEdges.Select(x => x.Item1 + "-" + x.Item2)); }
public static bool DFSGraphHasCycles(GraphAdjacentLists <int> graph) { return(DFSGraphEdgesRecursive(graph, graph.Vertices.First()).Any(edge => edge.Contains("back"))); }
public static IEnumerable <string> DFSGraphEdgesRecursive(GraphAdjacentLists <int> graph, int startNode, HashSet <int> discoveredNodes = null, HashSet <int> processedNodes = null, Dictionary <int, int> parentNodes = null, int parentNode = -1) { if (!graph.HasVertex(startNode)) { yield break; } var currentNode = startNode; if (discoveredNodes == null) { discoveredNodes = new HashSet <int>(); } if (processedNodes == null) { processedNodes = new HashSet <int>(); } if (parentNodes == null) { parentNodes = new Dictionary <int, int>(); } parentNodes[currentNode] = parentNode; discoveredNodes.Add(currentNode); foreach (var node in graph.GetAdjacentVertices(currentNode)) { if (processedNodes.Contains(node)) { if (graph.DirectedGraph == GraphAdjacentLists <int> .DirectedGraphEnum.Directed) { yield return("back edge: " + currentNode + "-" + node); } else { continue; } } else if (discoveredNodes.Contains(node)) { if (parentNode == node) { continue; } else { yield return("back edge: " + currentNode + "-" + node); } } else if (!discoveredNodes.Contains(node)) { parentNodes[node] = currentNode; yield return("tree edge: " + currentNode + "-" + node); foreach (var subEdge in DFSGraphEdgesRecursive(graph, node, discoveredNodes, processedNodes, parentNodes, currentNode)) { yield return(subEdge); } } } processedNodes.Add(currentNode); }