CS 314 Assignment 10: Do You Know the Way to San Jose Muleshoe?

Due: December 5, 2017.

Files: Cons.java   Graph.java   graphtest.java   graph.lsp   test10.lsp

This assignment may be done in Java or in Lisp.

For this assignment, it is legal to copy the algorithm code given in the class notes (online) as a starting point; it will be necessary to make some minor modifications.

In this assignment, we will investigate algorithms that find optimal routes on graphs: Dijkstra's algorithm, Prim's algorithm, and A* search. We will test the algorithms on a graph that represents cities and highways of Texas. Route-finding algorithms such as these are used in on-line services such as those provided by MapQuest and Google.

  1. Dijkstra's algorithm finds shortest paths to all nodes in a graph from a given starting node. In effect, it converts the graph into a tree, with the starting node as the root; each node has a cost (distance from the starting node) and a pointer to its parent in the tree. Reversing the parent pointer chain gives a minimum-cost path from the starting node to any node.

    1. Modify the given Dijkstra's algorithm so that it works (the initialization will have to be changed). Also keep a count of the number of nodes removed from the priority queue, and return this value as the return value of dijkstra; this is a measure of the cost of running dijkstra.

    2. Write a function Cons pathto(String city) that returns a path (list of city names) from the starting city to the specified city, assuming that Dijkstra has been run first so that parent pointers exist. The starting city should be at the front of the list.

  2. Make a version of Prim's algorithm that finds a minimum spanning tree for a graph. Return the total cost of the MST as the result of prim.

    1. Write a function int edgecost( Vertex start, Vertex goal) that returns the cost of the edge from start to goal, assuming that there is a direct edge between these two vertices.

    2. Write a function int pathcost( Vertex v) that returns the total cost of the path from v to the root of the tree.

    3. Write a method int totalcost( ), within the Graph class, that returns the total cost of all edges in the graph. You can simply add up the cost of all edges, but divide it by 2 since both directions of an undirected link are represented.

  3. Write a version of the A* algorithm that is done in a style similar to the Dijkstra algorithm. int astar( Vertex start, Vertex goal, Heuristic h ) has a goal as well as a start vertex. This algorithm assumes that we are only interested in an optimal path to the goal, rather than a path to all nodes as in Dijkstra.

    1. For A*, the priority of a node should be the estimated total cost of a path from the start to the goal through the node, .estimate, which is the known cost of a path from the start to the node (.cost, same as in Dijkstra) plus the estimated cost of the remaining distance to the goal, as given by the heuristic function h().

    2. A* should quit when a path to the goal has been found. Note that this is tested when the goal node is removed from the priority queue, not when it is inserted into the queue. Return the number of nodes removed from the priority queue as the value of A*; this is a measure of the cost of running A*.

    3. It is possible that a better path to some node may be found as the search proceeds. If a path better than the existing one is found, remove the existing one from the fringe using fringe.remove(), before adding the better path.

    4. We will examine a variety of heuristics for A*:

      1. dist computes the approximate great-circle distance (airline distance) between two cities. This is an excellent heuristic because it is a good estimate of road distance (and thus allows an efficient search) but never over-estimates.

      2. halfass computes half the great-circle distance. (A mule is the offspring of a male ass or donkey and a female horse.)

      3. zip returns 0.

      4. randombs returns a random fraction of great-circle distance.

      5. randomlies returns a random distance between 0 and 5000 miles. This may be an over-estimate, so that an optimal path is not guaranteed.

    5. Make a table (e.g. as a text file) to compare the number of nodes searched and path length for Austin to Muleshoe, Laredo to Haskell, and Dumas to Corsicana. Compare these for the programs Dijkstra, Prim (Austin to Muleshoe only, compare path length only), and A* using the heuristics dist, halfass, zip, randombs, and randomlies. Turn in this text file compare.txt as part of your assignment submission.