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.
- I would like to have all possible paths but most of the time, there is only 1 possible path.
- 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.
- 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;
}
}
}