|
SYS-CON Magazines
|
Top Three Links You Must Click On
Enterprise Java Developer's Journal: "Which Way?"
How to get men to ask for directions
Mar. 12, 2006 12:45 PM
The University of Southern California has a student body of about 40,000 people and a fairly large main campus. Around registration and graduation times, it often happens that parents or future students stop me asking for directions to buildings where they want to go. There are several large maps installed at key points on the campus and map leaflets are available at the Information Booths and are distributed during the orientation sessions. Although these maps are quite detailed, a visitor can be put off by the large number of buildings and, if the distance to the destination is long, people can get lost.
Thus the "Campus Directions" idea was born and within two months a pilot installation (with limited functionality and based on a somewhat older map) was available. We extended the idea and came up with an implementation that can cover any university campus or any relatively small area. The setup can be a fun two or three hour work and you get a program that shows step-by-step directions, with lengths and turns ("turn right," "turn left," "go straight") and a map image of the path trace similar to "yahoo maps" or "mapquest." A sample installation can be seen at http://romania.usc.edu/directions. (To test drive, please send me an e-mail.) Code samples can be downloaded from http://romania.usc.edu/directions/code/index.jsp. Additional help and a comprehensive list of setup steps can be found at http://romania.usc.edu/directions/help.
Functionality
There are two types of points and three types of links. A point can be "named," which means it can be the starting point or end point in searches, or it can be a "link point" when it only serves as a connection between named points. In Figure 1, UCC (University Computing Center) and DEN (Norris Dentistry School) are named points whereas the ones along the streets are link points. A link is the path element between two points (1 and 2). Links can be "bi-directional," "uni-directional 1-2," and "uni-directional 2-1." That means the path between points 1 and 2 can be traversed in either direction (1-2 and 2-1) or in only one direction (1-2 or 2-1.) That way the paths between two points A (e.g., UCC) and B (e.g., DEN) can be different if traversed from A to B rather than if traversed from B to A (as in the case when at least one path element along the way isn't bi-directional.) After the map has been initialized and the shortest paths calculated, a request for the shortest path between UCC and DEN returns the results shown in Figure 2 and Figure 3. The application automatically crops the map to show only what's meaningful (in this case the rectangle containing the path). The administrator doesn't enter the lengths. Instead they are computed from the distance in pixels multiplied by a factor that depends on the scale of the map. So the more accurate the map, the more exact the directions.
Theoretical Considerations I'll attempt to give a simplistic and visually driven description of the algorithm. Suppose we have the graph shown below; let's call the vertices (1,2,...5) points and the edges (1-2, 2-4, 4-5, etc.) links. Since there's no link between points 2 and 3, we'll say the distance is infinite (this is important in our implementation). If we want to calculate the shortest paths from point 1 (the source) to all the others, let's start with a two-row table like the one shown in Figure 5. Let's fill the cells with the distances we know already (see Figure 5). The distance from point 1 to itself is 0. We have the distances from 1 to 2 and 3. For the points that aren't linked directly to point 1 we write (for infinity.) Now let's pick the nearest point from 1; that's 2. Compare the distances from 1 to 3, 4, and 5 with the distances from 1 to 3, 4, and 5, but through the point 2. (e.g., d(1,4) > d(1,2) + d(2,4)) If the distance on the left is larger, replace it with the value on the right. In the example above the inequality is true since d(1,4) is infinite (no link). So d(1,4) will take the value d(1,2) + d(2,4) (see Figure 6). Note that from now on, there's a path between 1 and 4 and that's 1-2-4 (in the general case, it may not be the shortest, though). Repeat for points 3 and 5. (To digress a moment, the shortest distance to point 3 is obvious, since there's a direct link but, in general, when the graph edges represent cost, it may be cheaper to travel 1-2-4-3 than 1-3 directly. However, that's not the case here.) At this point our table should look like Figure 7. It already contains the shortest paths. But we have an overly zealous algorithm (greedy) so we'll continue by discarding point 2 and again find the closest point to 1 without considering 2. We repeat the steps above until all the points have been discarded. We have just found the shortest paths from point 1 to all the others. (To read the table, just move under the needed point. For example, d(p1,p4)=19.) In the example above we've found the shortest paths on the graph when the starting point was point 1. To find the shortest paths from each point to all the others, the procedure would have to be enclosed in another loop that iterates through the set of points and fixes a different one as the source each time. However, in our case, not every point in the set has to be considered since the (unnamed) "link points" can't act as the start or end of a path.
Technology and Implementation Now, before the application can be used, the map has to be "initialized" using the PixelMapper tool (the significant points added, linked, and the shortest distances calculated and saved into the database). Our graph will actually consist of the points on the map (see Figure 1) and the links between them. The activity diagram is shown in Figure 8. There are few basic entities that the application uses, some of which are shared by both the PixelMapper tool and the Web application. These types are:
The upper half of the image depicts the main classes used by the PixelMapper tool at map initialization, whereas the lower part shows the "model" layer of the Web application. The classes in the gray rectangle are shared by the two parts. The implementation of the algorithm Dijkstra::calculateShortestPaths produces two double-dimensional arrays (two square matrices) - a pointMatrix and a distanceMatrix. The first array is used to find the shortest path between any two given points in the initial PointList, and the second gives the corresponding distances. Figure 10 shows the pointMatrix partially populated, but containing enough data to find all the shortest paths when points 1 or 4 are used as the start points (refer to Figure 4.) Reader Feedback: Page 1 of 1
Subscribe to our RSS feeds now and receive the next article instantly!
Subscribe to the World's Most Powerful Newsletters
|
|
||||||||||||||||||||||||||||||||||||||