I was trying to find all possible paths, but I am having hard time keeping track of the paths that I have visited. Here is the code so far:
public void FindAllPaths(Node startNode, Node endNode)
{
queue.Enqueue(startNode);
while (queue.Count > 0)
{
var currentNode = queue.Dequeue();
foreach (var edge in currentNode.Edges)
{
if (edge.Visisted)
continue;
edge.Visisted = true;
queue.Enqueue(edge.TargetNode);
}
}
}
As stated previously, maintaining a
Visited
property on each edge will not work because a given edge may be present in multiple distinct paths. For example, the D/E edge will be traversed for both the A->D->E path and the A->B->C->D->E path.You need to maintain the current path for each node added to the queue:
You have to keep track of the paths visited for each route, not globally. For a breadth first approach each route needs a list of visited paths. For a depth first approach you can either keep a list of visited paths, or keep it global but unvisit the paths as you backtrack.
Getting the length of the path and the total weight will more or less do itself, once you keep track of the paths for each route.
With your current algorithm you would enqueue an item that has a node and a list of visited paths:
The QueueItem class is just:
I set up the paths this way:
If you go A-B-C-E then C will be marked as visited, but since C is also part of the path A-D-C-E you won't be able to find the later. Therefore a depth-first approach seems more appropriate, as it allows you to work on one path at a time. After you are finished with a path, you can clear the Visited-flags and continue with another path. I'm trying to scetch a solution in pseudo code:
Where
goal
is nodeE
in your example. You would callFindPath
with the start node