Unlike previous assignments, on this assignment you may work in pairs. If you choose to work with a partner, the handin procedures are as follows:
Guidelines for working in pairs: If you choose to work in pairs, you may split up the effort as you wish. However, each person should contribute some significant part of the work, and you should say how you decided to split things up in your handin. (E.g., I did part X, my partner did part Y, and we did part Z together.) Here are some suggestions for splitting up work (some of these will make more sense after you've read the rest of the handout):
This assignment consists of three tasks. The Task 1 is worth 20 points, Tasks 2 is worth 60 points, and task 3 is worth 20 points. 40 out of the 60 points for Task 2 are for getting a working heap-based implementation of a priority queue.
<address> is <N1> feet from intersection <I1> and <N2> feet from intersection <I2>.If it was a place name, the program responds by saying
<place name> is at <address> <address> is <N1> feet from intersection <I1> and <N2> feet from intersection <I2>.(The actual syntax is not important, and you can provide more information if your choose.) Furthermore, if the thing the user entered is ambiguous, the program should list the possible choices just like on Task 1 of assignment 6. You can run the executable we have provided for specific examples.
The way you will estimate the distance of the address to each intersection is by interpolation. For instance, if the block has street numbers 5100 to 5199, and is 550 feet long, then:
As a special case, if the minimum and maximum street addresses on the block are the same, then say that the address is halfway between the two.
Note: one thing you will need to do is to determine if the user is
giving you a place name or a street address. One way to do that is to
read in a string, and then see if the string begins with a digit. If
it does not begin with a digit, then this string is a place name (you
can assume that no place names begin with digits). Otherwise, if the string
does begin with a digit, then this means the string is a street
number and you want to read in a second string to get the street name.
One thing you will need to do is to convert your first string into a
number. A convenient way to do that is to use the atoi
function defined in <stdlib.h>. E.g.,
street_number = atoi(string);
where street_number is an int and string is a
character array. You can also use sscanf.
Enter a place name or street address: Blu Blum's_Barbeque is at address 355 S_Highland_Ave Enter a place name or street address: Bru Bruce's_Beach_Party is at address 711 Copeland_St Starting at 355 S_Highland_Ave, go to intersection 179, then on Elwood_St to intersection 192, then on Elwood_St to intersection 206, then on Elwood_St to intersection 217, then on Elwood_St to intersection 227, then on Elwood_St to intersection 268, then on Elwood_St to intersection 284, then on Elwood_St to intersection 295, then on Summerlea_St to intersection 275, then on Elmer_St to intersection 294, then on Elmer_St to intersection 314, then on Elmer_St to intersection 320, then on Elmer_St to intersection 330, then on Elmer_St to intersection 340, then on Elmer_St to intersection 348, then on Elmer_St to intersection 354, then on Elmer_St to intersection 359, then on Elmer_St to intersection 365, then on Copeland_St to 711 Copeland_St Total distance traveled: 3578 feet.(Your code may produce a total distance that differs by a foot or so from our code depending on how you do the rounding of Task 1.)
You may wish to treat the case in which the start and end are on the same block as a special case. For instance:
Enter a place name or street address: Ali Ali_Baba is at address 404 S_Craig_St Enter a place name or street address: Sta Star_Of_India is at address 412 S_Craig_St Just walk down the block!
Your program should run in time O(m logm) where m is the total number of edges in your graph. In order to do this, your program should use a heap-based implementation of a priority queue. This priority queue should allow one to insert an item with a priority value, to perform a remove_min operation to remove the item with the smallest priority value, and perhaps to perform a decrease_value operation to decrease the priority value of some item already inside the pqueue as well. (The last feature is not necessary - it depends on your search routine).
Your program should use interpolation (as in Task 1) to figure out the distances from the start and end locations to the ends of their respective blocks.
A programming hint: if you put print statements into your insert and remove functions that let you know what you're inserting and what you're removing, it will help you debug your code. Also, you will need to decide on an interface between your path-finding code and your path-printing code. One nice way to do this is to have your path-finding code return its parent array, where you may wish to have each element of this array contain more information than just the parent.
A good test case on the small database is to start at 5070
Forbes and go to 5300 Wilkins, and then try from 5080 Forbes to 5300
Wilkins. These should take different routes.
Enter a place name or street address: Blu Blum's_Barbeque is at address 355 S_Highland_Ave Enter a place name or street address: Bru Bruce's_Beach_Party is at address 711 Copeland_St Starting at 355 S_Highland_Ave head in the direction of increasing street number Go for 367 feet Turn right onto Elwood_St Go for 1604 feet Turn right onto Summerlea_St Go for 156 feet Turn left onto Elmer_St Go for 1394 feet Turn left onto Copeland_St Go for 57 feet and stop at number 711 Total distance traveled: 3578 feet.This is a bit trickier than it looks. For instance, how can you tell if you are making a right turn or a left turn? Below is a fragment of code that you can use or modify that will help you do that.
/* Suppose that xcoords is an array of all the x coordinates and ycoords is an array of all the y coordinates. This routine, given a start, middle, and end intersection (e.g., 284, 295, and 275) figures out what kind of turn (right or left) was made at the middle intersection. Here's the idea: we want to tell if the angle between two vectors is < or > 180 degrees. So, rotate the first vector by 90 degrees and then see if the dot prodoct is postive. */ char *which_way(int start, int middle, int end) { /* these are the rotated ones (which is why they look weird) */ int x0 = ycoords[middle] - ycoords[start]; int y0 = xcoords[start] - xcoords[middle]; int x1 = xcoords[end] - xcoords[middle]; int y1 = ycoords[end] - ycoords[middle]; int result = x0*x1 + y0*y1; if (result > 0) return "right"; else return "left"; }
For debugging purposes you might want to make your code output the intersections numbers too, while you're getting it working. We have placed executables into the assign7 directory that you can use to help you test out your program.
Good luck!