예제 #1
0
        /// <summary>
        /// The algorithm for BFS is almost exactly the same as for DFS except it uses
        /// a first in, first out (FIFO) queue instead of a stack.
        /// </summary>
        /// <typeparam name="TNode"></typeparam>
        /// <typeparam name="TEdge"></typeparam>
        /// <param name="graph"></param>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static SearchResult <TNode, TEdge> SearchBFS <TNode, TEdge>(this SparseGraph <TNode, TEdge> graph, int source, int target = -1)
            where TNode : GraphNode
            where TEdge : GraphEdge, new()
        {
            // reset search conditions
            visited = new Visit[graph.NumNodes];
            route   = Enumerable.Repeat(-1, graph.NumNodes).ToArray();
            SearchResult <TNode, TEdge> result = new SearchResult <TNode, TEdge> {
                Source = source, Target = target
            };
            // Create a queue of edges
            Queue <TEdge> queue = new Queue <TEdge>();
            // create a dummy edge and put on the queue
            TEdge dummy = new TEdge {
                From = source, To = source, Cost = 0
            };

            queue.Enqueue(dummy);
            //mark the source node as visited
            visited[source] = Visit.Visited;
            // while there are edges in the stack keep searching
            while (queue.Count > 0)
            {
                // grab the next edge
                TEdge next = queue.Dequeue();
                // make a note of the parent of the node this edge points to
                route[next.To] = next.From;
                // put it on the tree. (making sure the dummy edge is not placed on the tree)
                if (next != dummy)
                {
                    result.SpanningTree.Add(next);
                }
                // if the target has been found the method can return success
                if (next.To == target)
                {
                    result.Found = true;
                    SetPathToTarget(result, source, target);
                    return(result);
                }

                // push the edges leading from the node this edge points to onto
                // the queue (provided the edge does not point to a previously
                // visited node)
                foreach (TEdge edge in graph.Edges(next.To))
                {
                    if (visited[edge.To] == Visit.Unvisited)
                    {
                        queue.Enqueue(edge);
                        visited[edge.To] = Visit.Visited;
                    }
                }
            }
            // no path to target
            return(result);
        }
예제 #2
0
 public static void Print <TNode, TEdge>(this SparseGraph <TNode, TEdge> graph)
     where TNode : GraphNode
     where TEdge : GraphEdge, new()
 {
     Console.WriteLine($"Graph is directional: {graph.IsDigraph}");
     Console.WriteLine($"Graph is empty: {graph.IsEmpty}");
     Console.WriteLine($"Next available slot: {graph.NextNodeIndex}");
     Console.WriteLine($"Number of nodes: {graph.NumNodes}");
     Console.WriteLine($"Number of active nodes: {graph.NumActiveNodes}");
     Console.WriteLine($"Number of edges: {graph.NumEdges}");
     Console.WriteLine("----------------------------");
     Console.WriteLine("Nodes:");
     foreach (TNode node in graph.Nodes)
     {
         Console.Write($"{node.Index}: ");
         foreach (TEdge edge in graph.Edges(node.Index))
         {
             Console.WriteLine($"\t{edge.From}->{edge.To}::{edge.Cost}");
         }
         Console.WriteLine();
     }
     Console.WriteLine("----------------------------");
 }