简体   繁体   English

如何在 .NET 应用程序中实现广度优先搜索 (BFS) 算法以查找从一个点到另一个点的路径?

[英]How to implement Breadth First Search (BFS) algorithm in a .NET application to find a path from point to another point?

在此处输入图像描述

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.问题的简化版本:我想找到从 A 点到 E 点的所有线。 Result: L1, L3, L6, L7, L8

  1. I would like to have all possible paths but most of the time, there is only 1 possible path.我想拥有所有可能的路径,但大多数时候,只有 1 条可能的路径。
  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. A 到 E 与 E 到 A 相同,因此哪个方向并不重要,但返回解决方案中的行顺序对于跟踪目的很重要。
  3. I show a WinForm sample but I do not need a graphical solution.我展示了一个 WinForm 示例,但我不需要图形解决方案。 It is for the demonstration purpose.这是为了演示的目的。

From the help, I know I need to implement a graph with BFS algorithm.从帮助中,我知道我需要用 BFS 算法实现一个graph 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.我试图实现这个例子https://www.geeksforgeeks.org/print-paths-given-source-destination-using-bfs/但我被困在如何实现输入是List<Line>而不是List<integer>的方法上List<integer>来自示例。

     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我有线Line

 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);
        }

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这里有一个使用 HashSet 和 Queue 方法的好例子: 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;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM