CS136, Lecture 30

      1. Adjacency lists
        1. Representation:
    1. Applications
      1. Map coloring problem:
      2. Traversal problems

Adjacency lists

Representation:

An adjacency list is composed of a list of nodes or vertices. Hanging off of each node or vertex is a linked list of edges which are adjacent to that node.

Vertices Edges

Applications

Map coloring problem:

The map coloring problem is to color the states in a map in as few colors as possible so that no two adjoining states are of the same color.

An equivalent problem is to color the nodes of the corresponding graph so every edge has nodes of different colors. (See the graph obtained from the Northeast states - imagine making sure all capitals of adjacent states are colored different colors.)

We can color the following graph with only three colors:

Some however, require 4 colors:

An important mathematical result from the late 1970's shows that 4 colors are always enough for planar graphs (satisfying some very reasonable conditions).

Why should this remind you of course scheduling?

Traversal problems

Wish to serve as travel agent for Berkshire Airlines. Process customer requests to fly from origin city to destination city. Start by only checking if possible to fly from origin to destination.

Input files:

FlightFile: Each line is pair of city names representing origin and destination of one (leg of one) flight.

User types in names of pairs of cities. Program responds with message as to whether an itinerary is possible.

Begin by creating graph from the file.

When get request, begin exhaustive search of all cities accessible from origin city until either find destination or no more cities accessible.

How can we do search?

Start at origin, visit it to see if what looking for

If not found go to city, C1, connected to it

Search it and all connected to it

If not found check other neighbors and cities connected to them until find it or no more neighbors:

static boolean isPath(Graph g, Object startLabel, Object finishLabel)
{
    g.visit(startLabel);
    if (startLabel.equals(finishLabel))
        return true;
    else
    {
        Iterator nbrIterator;
        boolean found = false;
        for (nbrIterator  = g.neighbors(vertexLabel); 
                nbrIterator.hasMoreElements() && !found;
                nbrIterator.nextElement())
        {
            Object neighbor = nbrIterator.value();
            if (!g.isVisited(neighbor))
                found = isPath(g,neighbor,finishLabel);
        }
        return found;
    }
}

Can call as follows:
    g.reset();
    if (isPath(g,sourceLabel,destinationLabel))
    {...};

Can find all nodes connected to another by similar program where make into procedure:

reachableFrom(g,startLabel)

and don't use "found" to stop search. Then can find if destinationLabel is reachable from startLabel by calling procedure and then testing to see if destinationLabel "isVisited".

Can also do these iteratively:

static boolean isPath(Graph g, Object startLabel, Object finishLabel)
{
    Stack s = new StackList();
    s.push(startLabel);
    g.reset();
    while (!s.isEmpty())
    {
        Object current = s.pop();
        if (!g.isVisited(current))
        {
            g.visit(current);
            if (current.equals(finishLabel))
                return true;
            for (Iterator nbrIterator  = g.neighbors(vertexLabel); 
                                    nbrIterator.hasMoreElements();
                                    nbrIterator.nextElement())
                s.push(nbrIterator.value());
        }
    }
    return false;
}

Again easy to modify to mark all reachable vertices.

What order does this do search in?

What would happen if we used a queue instead of a stack?

What if we wanted to classify all vertices in terms of which component they are in?