Home > Net >  How to implement Breadth First Search (BFS) algorithm in a .NET application to find a path from poin
How to implement Breadth First Search (BFS) algorithm in a .NET application to find a path from poin

Time:08-13

enter image description here

This is related to my question yesterday regarding how to approach this problem. I learned useful concepts from the answers but I am unable to adapt the theory to the coding. This is for a system routing application. The simplified version of the issue: I would like to find all of the lines from Point A to E. Result: L1, L3, L6, L7, L8 based on the graphic above.

  1. I would like to have all possible paths but most of the time, there is only 1 possible path.
  2. A to E is the same as E to A so which direction is not important but the order of the lines from the returned solution is important for tracing purposes.
  3. I show a WinForm sample but I do not need a graphical solution. It is for the demonstration purpose.

From the help, I know I need to implement a graph with BFS algorithm. I tried to implement this example https://www.geeksforgeeks.org/print-paths-given-source-destination-using-bfs/ but I got stuck on how to implement the method that input is List<Line> instead of List<integer> from the example.

     List<List<Line>> FindPaths(List<Line> InputLines, Point src, Point des)
     {
     }
       // var A = myList[0].P1; 
       // var E = myList[7].P2; 

       // var paths = FindPaths(myList,A, E);

I have Line class

 public class Line
    {
        public string Name { get; set; }
        public Point P1 { get; set; }
        public Point P2 { get; set; }

        public Line(string name, Point p1, Point p2)
        {
            Name = name;
            P1 = p1;
            P2 = p2;
        }
    }

and points, lines, and are defined as following

        List<Line> myList;
        private void DrawSample()
        {
            //Point definitions
            var L1_P1 = new Point(40, 40); //Point A
            var L1_P2 = new Point(100, 100);

            var L2_P1 = new Point(100, 100);
            var L2_P2 = new Point(40, 160); //Point B

            var L3_P1 = new Point(100, 100);
            var L3_P2 = new Point(180, 100);

            var L4_P1 = new Point(180, 100);
            var L4_P2 = new Point(180, 25); //Point C

            var L5_P1 = new Point(180, 100);
            var L5_P2 = new Point(220, 165); //Point D

            var L6_P1 = new Point(180, 100);
            var L6_P2 = new Point(260, 100);

            var L7_P1 = new Point(260, 100);
            var L7_P2 = new Point(350, 100);

            var L8_P1 = new Point(350, 100);
            var L8_P2 = new Point(480, 100);//Point E

            //Line definitions
            var L1 = new Line("L1", L1_P1, L1_P2);
            var L2 = new Line("L2", L2_P1, L2_P2);
            var L3 = new Line("L3", L3_P1, L3_P2);
            var L4 = new Line("L4", L4_P1, L4_P2);
            var L5 = new Line("L5", L5_P1, L5_P2);
            var L6 = new Line("L6", L6_P1, L6_P2);
            var L7 = new Line("L7", L7_P1, L7_P2);
            var L8 = new Line("L8", L8_P1, L8_P2);

            myList = new List<Line>();
            myList.Add(L1);
            myList.Add(L2);
            myList.Add(L3);
            myList.Add(L4);
            myList.Add(L5);
            myList.Add(L6);
            myList.Add(L7);
            myList.Add(L8);

            //Graphic
            var brush = new SolidBrush(Color.Blue);
            var pen = new Pen(Color.Black, 2);

            //panelCanvas is just a WinForm Panel
            var canvas = panelCanvas.CreateGraphics();

            canvas.DrawLine(pen, L1.P1, L1.P2); //L1
            canvas.DrawLine(pen, L2.P1, L2.P2); //L2
            canvas.DrawLine(pen, L3.P1, L3.P2); //L3
            canvas.DrawLine(pen, L4.P1, L4.P2); //L4
            canvas.DrawLine(pen, L5.P1, L5.P2); //L5
            canvas.DrawLine(pen, L6.P1, L6.P2); //L6
            canvas.DrawLine(pen, L7.P1, L7.P2); //L7
            canvas.DrawLine(pen, L8.P1, L8.P2); //L8

            canvas.DrawString("L1", new Font("Tohoma", 10), brush, 70, 50);
            canvas.DrawString("L2", new Font("Tohoma", 10), brush, 70, 140);
            canvas.DrawString("L3", new Font("Tohoma", 10), brush, 132, 80);
            canvas.DrawString("L4", new Font("Tohoma", 10), brush, 184, 60);
            canvas.DrawString("L5", new Font("Tohoma", 10), brush, 180, 135);
            canvas.DrawString("L6", new Font("Tohoma", 10), brush, 220, 80);
            canvas.DrawString("L7", new Font("Tohoma", 10), brush, 300, 80);
            canvas.DrawString("L8", new Font("Tohoma", 10), brush, 420, 80);

            //Markings
            canvas.DrawString("X", new Font("Tohoma", 10, FontStyle.Bold), brush, 94, 92);
            canvas.DrawString("X", new Font("Tohoma", 10, FontStyle.Bold), brush, 174, 92);
            canvas.DrawString("X", new Font("Tohoma", 10, FontStyle.Bold), brush, 260, 92);
            canvas.DrawString("X", new Font("Tohoma", 10, FontStyle.Bold), brush, 350, 92);

            canvas.DrawString("A", new Font("Tohoma", 10, FontStyle.Bold), new SolidBrush(Color.Red), 32, 25);
            canvas.DrawString("B", new Font("Tohoma", 10, FontStyle.Bold), new SolidBrush(Color.Red), 40, 160);

            canvas.DrawString("C", new Font("Tohoma", 10, FontStyle.Bold), new SolidBrush(Color.Red), 174, 10);
            canvas.DrawString("D", new Font("Tohoma", 10, FontStyle.Bold), new SolidBrush(Color.Red), 220, 165);
            canvas.DrawString("E", new Font("Tohoma", 10, FontStyle.Bold), new SolidBrush(Color.Red), 480, 92);
        }

CodePudding user response:

There's a great example using a HashSet and Queue method here: https://www.koderdojo.com/blog/breadth-first-search-and-shortest-path-in-csharp-and-net-core

using System.Collections.Generic;

namespace KoderDojo.Examples {
    public class Algorithms {
        public HashSet<T> BFS<T>(Graph<T> graph, T start) {
            var visited = new HashSet<T>();

            if (!graph.AdjacencyList.ContainsKey(start))
                return visited;
                
            var queue = new Queue<T>();
            queue.Enqueue(start);

            while (queue.Count > 0) {
                var vertex = queue.Dequeue();

                if (visited.Contains(vertex))
                    continue;

                visited.Add(vertex);

                foreach(var neighbor in graph.AdjacencyList[vertex])
                    if (!visited.Contains(neighbor))
                        queue.Enqueue(neighbor);
            }

            return visited;
        }
    }
}
  • Related