Answer the question
In order to leave comments, you need to log in
Finding all routes of a C# graph?
There is a graph described by a matrix
0 1 1 1 0 0 0
1 0 0 0 0 0 0
1 0 0 1 0 0 1
1 0 1 0 0 1 0
0 0 0 0 0 1 1
0 0 0 1 1 0 1
0 0 1 0 1 1 0
It is necessary to build all the routes to the vertex x from the vertex v
Here is what I wrote
private void dfs(int[][] a, ref bool[] visited, int n, int v, int x, ref int cnt, ref List<List<int>> p, ref List<int> r)
{
if (v == x)
{
cnt++;
r.Add(x + 1);
p.Add(r);
r = new List<int>();
return;
}
visited[v] = true;
r.Add(v + 1);
for (int i = 0; i < n; i++)
{
if (a[v][i] == 1 && !visited[i])
{
dfs(a, ref visited, n, i, x, ref cnt, ref p, ref r);
}
}
visited[v] = false;
r.Remove(v + 1);
}
Answer the question
In order to leave comments, you need to log in
Here is the modified algorithm, it works correctly.
private void findRoute(int[][] a, int v, int dest, int n, bool[] visited, string route)
{
if (v == dest)
{
richTextBox1.Text += route + "\n";
}
else
{
visited[v] = true;
for (int i = 0; i < n; i++)
{
if (a[v][i] == 1 && !visited[i])
{
findRoute(a, i, dest, n, visited, route + (i+1) + " ");
}
}
visited[v] = false;
}
}
In my opinion, your recursion is not organized correctly. The point is that r is passed by reference to all search branches. And if one of these branches succeeds, r is set to zero, thus discarding the competing paths. In addition, in the search loop, r should also always contain the same thing (i.e. the path to the current top v
. But in your code this is not the case, because r will change inside the recursive call.
I'm not sure if everything else is correct, but I would change:
dfs(a, ref visited, n, i, x, ref cnt, ref p, ref r);
dfs(a, ref visited, n, i, x, ref cnt, ref p, r.ToArray());
class Program
{
public struct Path {
public List<int> Vertexes { readonly get; private set; }
public Path(int vertex) {
this.Vertexes = new List<int>();
this.Vertexes.Add(vertex);
}
public Path(List<int> vertexes, int vertex) {
if (vertexes != null) {
this.Vertexes = new List<int>(vertexes);
}
else {
this.Vertexes = new List<int>();
}
this.Vertexes.Add(vertex);
}
public Path Add(int vertex) {
Path p = new Path(this.Vertexes, vertex);
return p;
}
public bool hasVertex(int vertex) {
return Vertexes.Contains(vertex);
}
public int LastVertex() {
return Vertexes.Last();
}
}
public static List<Path> RunDfs(in int[,] graph, int n, in Path currentPath, int targetVertex) {
int currentVertex = currentPath.LastVertex();
if (currentVertex == targetVertex) {
return new List<Path> { currentPath };
}
else {
List<Path> result = new List<Path>();
for (int i = 0; i < n; i++) {
if (graph[currentVertex,i] == 1 && ! currentPath.hasVertex(i) ) {
List<Path> newPaths = RunDfs(graph, n, currentPath.Add(i), targetVertex );
result.AddRange(newPaths);
}
}
return result;
}
}
static void Main(string[] args) {
int[,] graph = { {0,1,1,0},{0,0,0,1},{0,1,0,0}, {0,0,0,0}};
Path curPath = new Path().Add(0);
List<Path> paths = RunDfs(graph, 4, curPath, 3);
Console.WriteLine("Hello World!");
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question