示例#1
0
        // Uninformed graph searches, or blind searches as they are sometimes
        // known, search a graph without regard to any associated edge costs.They
        // can distinguish individual nodes and edges however, enabling them to
        // identify a target node or to recognize previously visited nodes or edges.
        // This is the only information required to either completely explore a graph
        // (to visit every node) or find a path between two nodes.
        static void Main(string[] args)
        {
            // Given a source node, the depth first search can only guarantee that
            // all the nodes and edges will be visited in a connected graph.
            SparseGraph <GraphNode, GraphEdge> g = new SparseGraph <GraphNode, GraphEdge>(false);

            g.AddNode(new GraphNode(0));
            g.AddNode(new GraphNode(1));
            g.AddNode(new GraphNode(2));
            g.AddNode(new GraphNode(3));
            g.AddNode(new GraphNode(4));
            g.AddNode(new GraphNode(5));

            g.AddEdge(new GraphEdge(0, 1));
            g.AddEdge(new GraphEdge(0, 2));
            g.AddEdge(new GraphEdge(1, 4));
            g.AddEdge(new GraphEdge(2, 3));
            g.AddEdge(new GraphEdge(3, 4));
            g.AddEdge(new GraphEdge(4, 5));
            g.AddEdge(new GraphEdge(3, 5));
            //
            var dfs = g.SearchDFS(4, 2);

            dfs.Print();
            var bfs = g.SearchBFS(4, 2);

            bfs.Print();
            var ds = g.SearchDijkstra(4, 2);

            ds.Print();
        }
示例#2
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);
        }
示例#3
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("----------------------------");
 }