0

I've implemented a DFS recursive algorithm to find ALL paths between two nodes on a directed graph. Currently, my algorithm is finding approximately half of the total paths to find (I checked on an online tool how many possible paths there should be). I'm not sure where my algorithm is going awry. I have checked a bunch of different posts and it seems to be what others have implemented but I think I may have overlooked something. This is my first pathfinding algorithm and I seem to be stumbling over my first hurdle. I am not allowed to use inbuilt ADTS and therefore have built my own. Any help is appreciated as I am really pulling my hair out over this one. Please let me know if you need further information/code.

PATH FINDING

private void findPaths(String current, String target, LinkedList<String> currPath)
{
    Edge edge;

    if(current == target)
    {
        System.out.println(curPath.toString());
        return;
    }
    for (Vertex vertex: current.getAdjacent()))
    {
        Edge edge = getEdge(current+vertex);
        if(!edge.getVisited())
        {
            edge.setVisited;
            curPath.insertLast(vertex);
            findPaths(vertex, target, currPath);
            curPath.removeLast()
        }
    }
    edge.clearVisited()
}

edited for readability.

evie
  • 73
  • 1
  • 8
  • can you show the Vertex class ? – Maaddy Oct 22 '21 at 13:24
  • 1
    can you show, for an example graph, actual vs expected output?. Also, consider posting [minimal-but-complete code](https://stackoverflow.com/help/minimal-reproducible-example) to make it easier to answer your question. – tucuxi Oct 22 '21 at 13:28
  • "Currently, my algorithm is finding approximately half of the total paths to find", can you add at least one simple case? – Huy Nguyen Oct 22 '21 at 14:21
  • 1
    You mark an edge as used, so you can never use the same edge in two different paths. An edge can only be used once in a given path, but it could be used again in another path, right? – David Conrad Oct 22 '21 at 14:22

1 Answers1

1

I assume that the problem is in this code fragment:

for (Vertex vert1 : current.getVerts())      // say you have 4 unvisited edges
{
    label = vert1.toString();
    if(!getEdge(current+label).getVisited()) 
    {
        getEdge(current+label).setVisited(); // you will mark the 4 as visited 
        paths.addToPath(label);
        findPaths(vert1, target, paths);
        paths.removeFromPath();
    }
}
getEdge(current+label).clearVisited();      // but unmark only the last one 

You should replace it with

for (Vertex vert1 : current.getVerts())
{
    label = vert1.toString();
    if(!getEdge(current+label).getVisited())
    {
        getEdge(current+label).setVisited();   // mark this edge
        paths.addToPath(label);
        findPaths(vert1, target, paths);
        paths.removeFromPath();
        getEdge(current+label).clearVisited(); // unmark this edge
    }
}

Or even cleaner, you can refactor your code as follows:

private void findPaths(Vertex current, String target, Paths<String> paths)
    if(current.label.equals(target))
    {
        System.out.println(paths.getCurrPath());
        return;
    }
    for (Vertex vert1 : current.getVerts())
    {
        String label = vert1.toString();          // declare&initialize in loop
        Edge e = getEdge(current+label);          // lookup only once
        if( ! e.getVisited())
        {
            e.setVisited();
            paths.addToPath(label);
            findPaths(vert1, target, paths);
            paths.removeFromPath();
            e.clearVisited();
        }
    }

}
tucuxi
  • 17,561
  • 2
  • 43
  • 74
  • This puts me into an endless loop. Although the code does look cleaner. – evie Oct 22 '21 at 14:03
  • Maybe instead I should remove the visited field from the edge and instead check the current path to see if it holds the edge – evie Oct 22 '21 at 14:08
  • My intuition is that you only want to clear paths as visited after reaching the destination. – David Conrad Oct 22 '21 at 14:23
  • That's what I thought my previous algorithm was doing until I figured it wasn't. How would you suggest clearing the edges once a path has been found? – evie Oct 22 '21 at 14:33
  • Big uhuh moment. Finally got it by going through your code. Thank you – evie Oct 22 '21 at 17:18