CompSci-61B Lab 9b
Graphs

Instructor: Prof. Robert Burns

Graphs are generalizations of linked lists. Nodes in a graph may link to any other node in the graph -- including itself! Graphs can represent networks of interconnected objects -- for example, a roadmap can be stored in a graph. A "digraph" is a directed graph, with from-to relationships in the network. A "graph" is bidirectional in its links. The challenges in dealing with graphs and digraphs are (1) how to store the links, and (2) how to traverse the nodes.

A node in graphs (and digraphs) is called "vertex" and a link is called an "edge". In linked lists, nodes contain additional information besides an entry value -- they contain links to adjacent nodes. In graphs, vertices also contain additional information, but it is to support traveral. In linked lists, the links are stored inside the nodes, plus there are separate head, tail, and current links. In graphs, since there are so many link possibilities, the edges are stored in separate data structures.

Two popular ways to represent edges are (1) adjacency matrices (which we will exercises in this lab assignment) and (2) adjacency lists. Adjacency matrices are like 2D arrays with a row and column for each vertex, and a mark in the matrix to indicate a connection or a from-to relationship between 2 vertices. (For graphs, the matrix can be triangular, since there are no from-to relationships.) An adjacency list is an array of lists, one for each vertex, containing references to all of its adjacent vertices. (Applied to graphs, this method require duplication of links.)

In this lab assignment, we'll develop a graph class to solve a shortest route problem for a roadmap, the data for which is stored in a text file of city names and distances between adjacent cities. The class will not be generic. Not all Java solutions have to be written for generic use, and this one is written a specific use. We will use the java.util.Map interface and the java.util.HashMap class for the adjacency matrix. We'll also make extensive use of the java.util.Queue interface, the java.util.List interface, and the java.util.LinkedList class, and the java.util.Stack class, and java.util.PriorityQueue class.

This assignment is worth 40 points, and consists of 1 exercise. Zero points will be awarded for programs with misspelled filenames, or incorrect case. Zero points will be awarded for programs that do not compile or run on the department's UNIX server. Partial points will be awarded for programs that are run but do not conform to all specifications, at the discretion of the grader. Be sure to complete both exercises and post the lab9b.jar before midnight of the due date, because there is a 5-point-per-day lateness penalty for late work. Check the course outline for due dates for lab assignments.



EXERCISE: Create The Program Structure (40 points)
Write ShortestRoute.java in package compsci61b.testing. Use a "digraph", because the implementation is easier. Here are the specs: Note that you don't need to deal with mileage until you get to the cheapest route implementation. Nor do you needprivate class VertexTemp until then.

Test the methods -- not all will be used in the final version of the program. Make sure that the methods can be called more than once and in any order. Follow the algorithms of chapter 30 in Carrano, and build the methids in the order of their appearance in the list above, starting with the 1-parameter constructor.

MAIN
Here is the main for this application:

  public static void main(String[] argv) throws Exception
  {
    BufferedReader cin = new BufferedReader(new InputStreamReader(System.in));   

    ShortestRoute s = new ShortestRoute("cities.txt");

    // print al city names
    System.out.print("\nEnter a city name to begin the listing of city names: ");
    String fromCity = cin.readLine();
    for (String city: s.getBreadthFirstTraversal("San Francisco"))
      System.out.print(city + ' ');
    System.out.println();

    while (true)
    {
      System.out.print("\nEnter the source city [blank to exit]: ");
      String fromCity = cin.readLine();
      if (fromCity.length() == 0) break;

      System.out.print("Enter the destination city [blank to exit]: ");
      String toCity = cin.readLine();
      if (toCity.length() == 0) break;

      Stack<String> r = new Stack(){};
      System.out.println("Total miles: " + s.getCheapestRoute(fromCity, toCity, r));  
      while (!r.empty()) System.out.println(" " + r.pop() + ' ');
  } }
VARIATIONS
If you prefer to write this as a graph instead of a digraph, go ahead. That would halve the number of entries in the adjacency table. You can store the verticies in something other than a List.

Each of the 4 traversal methods are worth -5 points if omitted. If you omit getBreadthFirstTraversal or getCheapestRoute which are used in the supplied main method, modify main to use the method(s) that you do have.

CONVERTING CITY NAMES TO VERTEX OBJECT REFERENCES
This should help to get you started:

  public ... get...(String startName, ...)
  {
    Vertex startVertex = null;

    for (Vertex v: vertexes)
    {
      v.reset();
      if (v.name.equalsIgnoreCase(startName)) startVertex = v;
      ...
    }
    if (startVertex == null || ...) return ...

    // now use the vertex(es) in the algorithm instead of the string names
    ...
TRAVERSING THE NEIGHBORS
All four traveral algorithms say "while frontVertex has a neighbor". Here's how to iterate the adjacency table:
    Edge key = new Edge(); // for key comparing only
    key.firstName = frontVertex.name;
    for (Vertex neighbor: vertexes)
    {
      key.secondName = neighbor.name;
      Edge edge = adjacencyTable.get(key);
      if (edge == null) continue; // no matching key
      ...if you get to here, "neighbor" is a neighbor...
Create your final version of lab9b.jar, with files from this and all previous labs. Post your lab9b.jar file to your student UNIX account for grading and credit.

[ Home | Contact Prof. Burns ]