//Iterative depth-first search that returns the node with the target data.
        public static GraphNode <T> BFS <T>(this SimpleGraph <T> graph, T target)
        {
            if (graph == null || graph.Nodes.Count == 0)
            {
                return(null);
            }

            var visited = new HashSet <GraphNode <T> >();
            var queue   = new DataStructures.Queue <GraphNode <T> >();

            queue.Enqueue(graph.Root);

            while (!queue.IsEmpty)
            {
                GraphNode <T> curr = queue.Dequeue();

                if (visited.Contains(curr))
                {
                    continue;
                }

                if (curr.Data.Equals(target))
                {
                    return(curr);
                }

                visited.Add(curr);
                foreach (GraphNode <T> neighbor in curr.Neighbors)
                {
                    queue.Enqueue(neighbor);
                }
            }

            return(null);
        }
Пример #2
0
        /// <summary>
        /// Traverse graph in breadth first order
        /// Returns traverse path as List
        /// Time Complexity: O(V+E)
        /// where V is number of vertices in the graph and E is number of edges in the graph
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="graph">Graph to be traversed</param>
        /// <param name="first">start point in graph</param>
        /// <returns>Traverse path</returns>
        public static List <T> BreadthFirstSearch <T>(IGraph <T> graph, T first)
        {
            List <T> result = new List <T>();

            DataStructures.Queue <T> queue = new DataStructures.Queue <T>();
            HashSet <T> visited            = new HashSet <T>();

            queue.Enqueue(first);

            while (!queue.IsEmpty())
            {
                T current = queue.Dequeue();
                result.Add(current);
                visited.Add(current);

                foreach (var neighbour in graph.GetNeighbours(current))
                {
                    if (!visited.Contains(neighbour))
                    {
                        queue.Enqueue(neighbour);
                    }
                }
            }

            return(result);
        }
        //Iterative depth-first search that returns the path to the target
        public static List <GraphNode <T> > BFSPathTo <T>(this SimpleGraph <T> graph, T target)
        {
            if (graph == null || graph.Nodes.Count == 0)
            {
                return(null);
            }

            var visited = new HashSet <GraphNode <T> >();
            var queue   = new DataStructures.Queue <GraphNode <T> >();

            queue.Enqueue(graph.Root);
            GraphNode <T> curr = null;
            var           path = new List <GraphNode <T> >();

            while (!queue.IsEmpty)
            {
                curr = queue.Dequeue();

                if (visited.Contains(curr))
                {
                    continue;
                }

                if (curr.Data.Equals(target))
                {
                    break;
                }

                visited.Add(curr);
                foreach (GraphNode <T> neighbor in curr.Neighbors)
                {
                    queue.Enqueue(neighbor);
                }
            }

            if (!curr.Data.Equals(target))
            {
                return(null);
            }

            while (curr.Origin != null && !curr.Equals(graph.Root))
            {
                path.Add(curr);
                curr = curr.Origin;
            }
            path.Add(curr);
            path.Reverse();

            return(path);
        }
Пример #4
0
        public void BreadthFirstSearch(TKey key, ProcessVertex preProcess = null, ProcessVertex postProcess = null)
        {
            var v = GetVertex(key);

            DataStructures.Queue <Vertex> vQueue = new DataStructures.Queue <Vertex>();
            v.Viewed = true;
            vQueue.Enqueue(v);
            preProcess?.Invoke(v);
            while (!vQueue.IsEmpty)
            {
                foreach (var vert in Nearest(vQueue.Peek().Key).Where(vrt => !vrt.Viewed))
                {
                    preProcess?.Invoke(vert);
                    vert.Viewed = true;
                    vQueue.Enqueue(vert);
                }
                v = vQueue.Dequeue();
                postProcess?.Invoke(v);
            }
        }
Пример #5
0
        /// <summary>
        /// Breadth-First Traversal (traverse nodes closer to the start node before the nodes that are farther). Complexity is linear.
        /// </summary>
        /// <param name="startingNode"></param>
        /// <param name="processNodeAction">Action delegate which is invoked for each node</param>
        public static void BreadthFirstTraversal(Node <TNodeValue, TLinkProperty> startingNode, Action <Node <TNodeValue, TLinkProperty> > processNodeAction)
        {
            if (startingNode == null)
            {
                throw new ArgumentNullException("startingNode");
            }
            if (startingNode.Graph == null)
            {
                throw new Exception("Node is not associated with a graph");
            }
            var mountedNodes = new Dictionary <Node <TNodeValue, TLinkProperty>, bool>(startingNode.Graph.NodesCount);

            var queue = new DataStructures.Queue <Node <TNodeValue, TLinkProperty> >();

            queue.Enqueue(startingNode);
            mountedNodes.Add(startingNode, true);

            while (queue.Count != 0)
            {
                var n = queue.Dequeue();
                if (processNodeAction != null)
                {
                    processNodeAction(n);
                }

                foreach (var l in n.Links)
                {
                    if (n == l.Node1 && !mountedNodes.ContainsKey(l.Node2))
                    {
                        queue.Enqueue(l.Node2);
                        mountedNodes.Add(l.Node2, true);
                    }
                    if (n == l.Node2 && !!mountedNodes.ContainsKey(l.Node1))
                    {
                        queue.Enqueue(l.Node1);
                        mountedNodes.Add(l.Node1, true);
                    }
                }
            }
        }