COMP 372: Project 1 --- Navigating Memphis

In this project, you will use the A* algorithm to find the fastest route between two locations in Memphis.

Your program should ask the user for three inputs: the name of a map file (in the same format as used in Project 0), then the IDs for two different locations on that map. Your program should use the A* algorithm to find the quickest driving route in terms of time between the two locations. Your program should print the following pieces of information in the format specified in the examples below.

Your algorithm should use the speed limit for each road to determine the time it takes to travel that particular road segment. You may assume speed changes are instantaneous, and you don't have to take traffic or stop lights (or other things which one would slow down for) into account.

You will notice that in order to calculate the travel time for a road segment, you will need the length of the road in miles as well as the speed limit. To do this from latitude and longitude coordinates, you should use this code that calculates great-circle distances on a sphere. (No, the earth is not perfectly spherical, but it's an OK approximation.) Remember to multiply the return value by 3960 to get the distance in miles! You can then use the distance in miles combined with the speed limit of the road in miles per hour, to compute the travel time in minutes.

Reminder: in the map files, longitudes come first, then latitudes. People tend to get these backwards, which messes up the great-circle calculations.

For g(n), use the travel time in minutes from the start state to the node n. For the heuristic value h(n), use the straight-line travel time from n to the goal state, assuming you could drive from node n to the goal at 65 miles per hour. We can use 65mph because that's the maximum speed limit of any Memphis road, so this h(n) will never overestimate the true travel time.

Implementing A*

Use the A* pseudocode in the book or from the handouts in class. While you may find online sources helpful in understanding the algorithm, you may encounter slight variations in different people's versions of the algorithm that will make it difficult for me to test your code and help you debug it if necessary.

Testing

For testing purposes (both for you and me), you must put a global constant at the top of your main program called DEBUG. If this set to true, then your program should, during the main A* loop, print three kinds of information as necessary: You should use this debugging output to make sure you are examining nodes in the same order that my solution is. You can set this to false when you get your program working so it doesn't clutter up your output, and I will use it when I check your output against mine when grading your solution. (It is possible there may be slight variations here due to Python/C++ implementations of floating-point numbers. Use doubles in C++.)

Location IDs

To test your program, I have collected the IDs for some Memphis landmarks, commonly-visited places, and some intersections near Rhodes.

Example runs

These examples use the all-memphis.txt map. Assuming the debugging flag is turned off, the first three all run in less than one second on my computer, and the last one takes less than five seconds.

What to turn in

Through Moodle, turn in your code. Make sure there is a DEBUG global constant that I can easily find.

Grading

You will be graded on correctness of your program (whether it gives the best path or tour), and whether the sequence of nodes expanded matches mine --- this guarantees you implemented A* correctly.

Fun ideas