Пример #1
0
        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);
        }
Пример #2
0
        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)));
        }
Пример #3
0
        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
                });
            }
        }
Пример #4
0
        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>()));
        }
Пример #5
0
        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));
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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));
        }
Пример #9
0
 public static bool DFSGraphHasCycles(GraphAdjacentLists <int> graph)
 {
     return(DFSGraphEdgesRecursive(graph, graph.Vertices.First()).Any(edge => edge.Contains("back")));
 }
Пример #10
0
        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);
        }