Dijkstra's All Sortest Path Algorithm The most complicated graph algorithm that we will examine in detail in ICS-23 is Dijkstra's All Shortest (least costly) Paths Algorithm. Given a starting node, it computes the shortest paths (in a directed graph with weighted edges; the edge weights must be all non-negative) to all nodes in a graph reachable from the starting node. The length of a path (and the measure of "shortness") is based on the sum-of-the-weights of all the edges on the path. Actually, I will call it an Extended version of Dijkstra's algorithm, because we will store enough information not only to compute the cost of the shortest paths, but to reconstruct them as well: what nodes/edges lie between the starting and ending nodes. The standard Dijkstra algorithm computes just the cost of all the shortest paths. This algorithm generalizes the reachability algorithm that we wrote in Programming Assignment #1, by finding not just all nodes reachable from a start node, but the minimum cost paths to reach each node (in the programming assigment each edge weight was assumed to be 1). GPS systems use a variant of this algorithm to search from where you are to where you want to go (but it stops when it finds the fastest way to get to that one location). This algorithm uses many collection classes to get its job done: a Graph, a Map, a Set, a Priority Queue, and a Stack. I will describe the algorithm in detail below, and then we will hand simulate it on a moderate-sized graph in class. You will implement this algorithm in Programming Assignment #5. Most data in the algorithm is stored as objects from a class named Info, which contains the name of a node, the cost of the minimum path to reach that node (initialzed to +infinity and updated in the algorithm until the minimum cost is found), and the name of the node BEFORE it on the shortest path (initialized to "" and updated in the algorithm). Objects in the Info class are ultimately stored in three collections: as the values in a Map (the key is the node name), as the values in a Priority Queue (with the lowest cost having the highest priority: this class contains a Comparator for this prioritization), and temporarily as the values in a Set. 0) Load and print a graph whose edges are labeled by integer values. 1) Declare the "infoMap" map and put each node in the graph as a key in the map, with its associated value a newly constructed/initialized object of Info. Note that the key for infoMap and the nodeName field in the infoMap are the same; this bit of redundancy helps keep the algoithm simple. 2) Prompt the user to enter a start node. When the user enters a legal start node in the graph, find the Info for this starting node in infoMap, and set its totalCost to 0 (since we start at that node, the cost to reach it is 0). 3) Declare the "considering" a priority queue Put all the infoMap values (not keys) into the priority queue. The comparator should look at the totalCost field in Info. 4) So long as the considering priority queue is not yet empty, process another node by a) Removing the highest priority value in the priority queue (the one whose cost is lowest -initially, the start node). Call this the "min" node. We are now guaranteed to know the least costly path from the start node to min. b) For every node d that is a destination from the min node, get d's Info using infoMap and see if the cost is infinite or greater than the cost of the path from the start node to min, plus the cost of the edge from min to d. If this sum is smaller, (1) update the cost in Info to this smaller number, (2) update the predecessor of d to be min, (3) put this Info into a set of "changed" Info objects. c) Use an iterator to remove all the changed Info objects from the priority queue (this is the first time we are doing anything significant with an iterator's remove method), and then re-add these objects (their cost -e.g., priority- is different) to the priority queue. d) Continue around the loop 5) When the loop finished, the Info values are filled in with the minimum cost to reach each node and the node preceding it on the minimum path. Print out this information 6) Repeatedly prompt the user for a stop node and show the minimum cost and minimum cost path to reach that node. By repeatedly following the predecessors in the map (a Stack would be useful here), we can reconstruct the entire minimimum cost path from the start node to any reachable node. Although I won't show the hand simulation here, I will do one in class and you should be able to hand simulate this algorithm, from memory. The steps listed above are very detailed when applied to actual Java data types: peforming the algorithm on the whiteboard will be reasonably fast and intuitive. We could have two different infoMaps: one for nodes whose minimum distance IS NOT YET known and one for nodes whose minimum distance IS known. When we do step 4a, after we remove the minimum value from the priority queue, we could remove it from the first map and put it in the second. In part 4b we would have to update only those nodes still in the first map. This would speed up the algorithm but not change its complexity class. Again, I called this algorithm an Extended version of Dijkstra's algorithm, because we will store enough information not only to compute the cost of the shortest paths, but to reconstruct them as well: what nodes/edges lie between the starting and ending nodes. The standard Dijstra algorithm computes just the cost of all the shortest paths. Assume we have a graph with N nodes and each node has O(N) edges. To build the initial heap is step 2 is O(N). The loop specified in step 4 loops once for each node, so it iterates N times. Each time it loops it executes parts a-c: part a is O(Log N), part b is O(N), and part c is O(N Log N), so the entire algorithm is N x O(N + Log2 N + N Log2 N) or O(N^2 Log2 N).