How to modify dijkstra algorithm to find all possible paths?

Zulu Z picture Zulu Z · Apr 14, 2013 · Viewed 15k times · Source

I know that could be asked before already but I cannot find it. I need to modify below dijkstra algorithm which works good for finding shortest path between 2 nodes but I need to find all possible paths also. I know it should be relatively easy to do this but so far I don't have idea how to do this simplest way. I'm using directed weighted graph.

    class Dijkstra
    {
        private List<Node> _nodes;
        private List<Edge> _edges;
        private List<Node> _basis;
        private Dictionary<string, double> _dist;
        private Dictionary<string, Node> _previous;

        public Dijkstra(List<Edge> edges, List<Node> nodes)
        {

            Edges = edges;
            Nodes = nodes;
            Basis = new List<Node>();
            Dist = new Dictionary<string, double>();
            Previous = new Dictionary<string, Node>();

            // record node 
            foreach (Node n in Nodes)
            {
                Previous.Add(n.Name, null);
                Basis.Add(n);
                Dist.Add(n.Name, double.MaxValue);
            }
        }

        /// Calculates the shortest path from the start
        ///  to all other nodes
        public void calculateDistance(Node start)
        {
            Dist[start.Name] = 0;

            while (Basis.Count > 0)
            {
                Node u = getNodeWithSmallestDistance();
                if (u == null)
                {
                    Basis.Clear();
                }
                else
                {
                    foreach (Node v in getNeighbors(u))
                    {
                        double alt = Dist[u.Name] + getDistanceBetween(u, v);
                        if (alt < Dist[v.Name])
                        {
                            Dist[v.Name] = alt;
                            Previous[v.Name] = u;
                        }
                    }
                    Basis.Remove(u);
                }
            }
        }

        public List<Node> getPathTo(Node d)
        {
            List<Node> path = new List<Node>();

            path.Insert(0, d);

            while (Previous[d.Name] != null)
            {
                d = Previous[d.Name];
                path.Insert(0, d);
            }

            return path;
        }

    public Node getNodeWithSmallestDistance()
        {
            double distance = double.MaxValue;
            Node smallest = null;

            foreach (Node n in Basis)
            {
                if (Dist[n.Name] < distance)       
                {
                    distance = Dist[n.Name];
                    smallest = n;
                }
            }

            return smallest;
        }


        public List<Node> getNeighbors(Node n)
        {
            List<Node> neighbors = new List<Node>();

            foreach (Edge e in Edges)
            {
                if (e.Origin.Equals(n) && Basis.Contains(n))
                {
                    neighbors.Add(e.Destination);
                }
            }

            return neighbors;
        }

       public double getDistanceBetween(Node o, Node d)
        {
            foreach (Edge e in Edges)
            {
                if (e.Origin.Equals(o) && e.Destination.Equals(d))
                {
                    return e.Distance;
                }
            }

            return 0;
        }


        public List<Node> Nodes
        {
            get { return _nodes; }
            set { _nodes = value; }
        }

        public List<Edge> Edges
        {
            get { return _edges; }
            set { _edges = value; }
        }

        public List<Node> Basis
        {
            get { return _basis; }
            set { _basis = value; }
        }

        public Dictionary<string, double> Dist
        {
            get { return _dist; }
            set { _dist = value; }
        }

        public Dictionary<string, Node> Previous
        {
            get { return _previous; }
            set { _previous = value; }
        }
    }
}

static void Main(string[] args)
        {
//Nodes initialisation goes here

Dijkstra d = new Dijkstra(_edges, _nodes);
d.calculateDistance(_dictNodes["A"]);
 List<Node> path = d.getPathTo(_dictNodes["C"]);
}

Answer

Zulu Z picture Zulu Z · Apr 20, 2013

OK, I have actually modified Dijkstra class to do BFS as well and it got me all possible routes. I added this method:

public void BreadthFirst(Edge graph, LinkedList<String> visited) 
{
    LinkedList<String> nodes = graph.adjacentNodes(visited.Last());

    // Examine adjacent nodes
    foreach (String node in nodes) 
    {
        if (visited.Contains(node))
        {
            continue;
        }

        if (node.Equals(endNode))
        {
            visited.AddLast(node);

            printPath(visited);

            visited.RemoveLast();

            break;
         }
     }

    // In breadth-first, recursion needs to come after visiting adjacent nodes
    foreach (String node in nodes)
    {      
        if(visited.Contains(node) || node.Equals(endNode))
        {
            continue;
        }

        visited.AddLast(node);

        // Recursion
        BreadthFirst(graph, visited);

        visited.RemoveLast();
    }
}

Usage would be like this:

Dijkstra d = new Dijkstra(_edges, _nodes);

LinkedList<String> visited = new LinkedList<string>();  //collecting all routes
visited.AddFirst(start);

d.BreadthFirst(graph, visited);