├── GraphResolver.PNG
├── README.md
├── GraphResolver.csproj
├── Model
├── Vertex.cs
├── Edge.cs
└── Graph.cs
├── GraphResolver.cs
├── GraphResolver.sln
└── Program.cs
/GraphResolver.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/access/GraphResolver/main/GraphResolver.PNG
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Graph Resolver Test Data:
2 | 
3 |
--------------------------------------------------------------------------------
/GraphResolver.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net5.0
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Model/Vertex.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace GraphResolver.Model
8 | {
9 | public class Vertex
10 | {
11 | public int Number { get; set; }
12 | public Vertex(int number) => Number = number;
13 | public bool Visited { get; set; }
14 | public override string ToString() => Number.ToString();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Model/Edge.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace GraphResolver.Model
8 | {
9 | public class Edge
10 | {
11 | public Vertex From { get; set; }
12 | public Vertex To { get; set; }
13 | public override string ToString() => $"({From}; {To})";
14 |
15 | public Edge(Vertex from, Vertex to)
16 | {
17 | From = from;
18 | To = to;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/GraphResolver.cs:
--------------------------------------------------------------------------------
1 | using GraphResolver.Model;
2 | using System;
3 | using System.Collections;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace GraphResolver
10 | {
11 | class GraphResolver
12 | {
13 | public static List> ConnectingPaths(List> graph, int node1, int node2)
14 | {
15 | var newGraph = new Graph();
16 |
17 | // init graph vertexes and edges
18 | foreach (var edge in graph)
19 | {
20 | var vertexFrom = newGraph.AddVertex(edge.Item1);
21 | var vertexTo = newGraph.AddVertex(edge.Item2);
22 | newGraph.AddEdge(vertexFrom, vertexTo);
23 | }
24 |
25 | return newGraph.GetRoutes(node1, node2);
26 | }
27 |
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/GraphResolver.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31410.357
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphResolver", "GraphResolver.csproj", "{3BD96597-5365-4DBF-A341-6E6CBD9CEC82}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {3BD96597-5365-4DBF-A341-6E6CBD9CEC82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {3BD96597-5365-4DBF-A341-6E6CBD9CEC82}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {3BD96597-5365-4DBF-A341-6E6CBD9CEC82}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {3BD96597-5365-4DBF-A341-6E6CBD9CEC82}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {59ABFC51-FAB2-446A-B415-D7B8F7643977}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace GraphResolver
5 | {
6 | class Program
7 | {
8 | // fill edges data for testing...
9 | private static List> _edges = new List>() {
10 | new Tuple(1, 2),
11 | new Tuple(1, 3),
12 | new Tuple(2, 4),
13 | new Tuple(3, 4),
14 | new Tuple(4, 5),
15 | new Tuple(4, 6),
16 | //------------------------
17 | new Tuple(5, 15),
18 |
19 | new Tuple(5, 7),
20 | new Tuple(6, 7),
21 | new Tuple(7, 8),
22 | new Tuple(7, 9),
23 | new Tuple(8, 10),
24 | new Tuple(9, 10),
25 | new Tuple(10, 11),
26 | new Tuple(10, 12),
27 |
28 | new Tuple(12, 120),
29 | new Tuple(120, 88),
30 |
31 |
32 | new Tuple(88, 33),
33 | new Tuple(88, 55),
34 | };
35 |
36 | static void Main(string[] args)
37 | {
38 | Console.WriteLine("GraphResolver started.");
39 |
40 | var result = GraphResolver.ConnectingPaths(_edges, 1, 4);
41 |
42 | foreach (var route in result)
43 | {
44 | Console.Write(string.Join(",", route.ToArray()));
45 | Console.WriteLine();
46 | }
47 |
48 | Console.WriteLine("GraphResolver finished.");
49 | Console.ReadLine();
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Model/Graph.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace GraphResolver.Model
8 | {
9 | public class Graph
10 | {
11 | private HashSet _UniqueVertexes = new HashSet();
12 | private List _Vertexes = new List();
13 | private List _Edges = new List();
14 | private List> _AvailableRoutes = new List>();
15 |
16 | public int VertexCount => _Vertexes.Count;
17 | public int EdgesCount => _Edges.Count;
18 |
19 | public Vertex AddVertex(int vertex)
20 | {
21 | var newVertex = new Vertex(vertex);
22 | if (_UniqueVertexes.Add(vertex))
23 | _Vertexes.Add(newVertex);
24 | else
25 | foreach (var v in _Vertexes)
26 | if (v.Number == vertex)
27 | return v;
28 | return newVertex;
29 | }
30 |
31 | public void AddEdge(Vertex from, Vertex to)
32 | {
33 | var edge = new Edge(from, to);
34 | _Edges.Add(edge);
35 | }
36 |
37 | public List GetToVertexesList(Vertex vertex)
38 | {
39 | var result = new List();
40 |
41 | foreach (var edge in _Edges)
42 | if (edge.From == vertex)
43 | result.Add(edge.To);
44 | return result;
45 | }
46 |
47 | public Vertex GetVertexByValue(int val)
48 | {
49 | foreach (var v in _Vertexes)
50 | if (v.Number == val)
51 | return v;
52 | return null;
53 | }
54 |
55 | public List> GetRoutes(int start, int finish)
56 | {
57 | // get start and finish Vertexes
58 | var startVertex = GetVertexByValue(start);
59 | var finishVertex = GetVertexByValue(finish);
60 |
61 | GenerateAvailableRoutes(startVertex, finishVertex);
62 |
63 | var neededList = new List>();
64 | foreach (var route in _AvailableRoutes)
65 | {
66 | if (route.Contains(start) && route.Contains(finish))
67 | {
68 | int startIdx = route.IndexOf(start);
69 | int finishIdx = route.IndexOf(finish);
70 | var routeVertexes = route.GetRange(startIdx, finishIdx - startIdx + 1);
71 | neededList.Add(routeVertexes);
72 | }
73 | }
74 |
75 | // remove duplicates
76 | var distinct = neededList.Select(x => new HashSet(x)).Distinct(HashSet.CreateSetComparer());
77 | var outList = new List>();
78 | foreach (var list in distinct)
79 | outList.Add(list.ToList());
80 | return outList;
81 | }
82 |
83 | private void GenerateAvailableRoutes(Vertex start, Vertex finish)
84 | {
85 | bool endOfBranch = false;
86 | var tmpRoute = new LinkedList();
87 | var currentVertex = start;
88 |
89 | tmpRoute.AddFirst(start);
90 | while (tmpRoute.Count > 0)
91 | {
92 | if (endOfBranch)
93 | {
94 | tmpRoute.RemoveLast();
95 | if (tmpRoute.Last != null)
96 | currentVertex = tmpRoute.Last.Value;
97 | }
98 |
99 | var neighborList = GetToVertexesList(currentVertex);
100 | if (neighborList.Count > 0)
101 | {
102 | bool hasNotVisited = false;
103 | foreach (var vertex in neighborList)
104 | {
105 | if (!vertex.Visited)
106 | {
107 | hasNotVisited = true;
108 | tmpRoute.AddLast(vertex);
109 | vertex.Visited = true;
110 | currentVertex = vertex;
111 | endOfBranch = false;
112 | break;
113 | }
114 | }
115 | if (!hasNotVisited)
116 | {
117 | if (!endOfBranch)
118 | CleanVisits(currentVertex);
119 | else
120 | {
121 | if (!endOfBranch)
122 | tmpRoute.RemoveLast();
123 | if (tmpRoute.Last != null)
124 | currentVertex = tmpRoute.Last.Value;
125 | }
126 | }
127 | }
128 | else
129 | {
130 | endOfBranch = true;
131 | _AvailableRoutes.Add(tmpRoute.Select((item) => (item.Number)).ToList());
132 | }
133 | }
134 | }
135 |
136 | private void CleanVisits(Vertex currentVertex)
137 | {
138 | foreach (var vertex in GetToVertexesList(currentVertex))
139 | {
140 | vertex.Visited = false;
141 | CleanVisits(vertex);
142 | }
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------