CS136, Lecture 30

      1. Traversal problems
      2. Topological sort uses depth first search:
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
    {
        boolean found = false;
        for (Iterator 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;
}

Complexity: Start by pushing and popping original vertex. Then for each unvisited node, push all neighbors on stack. Sum of degrees of all vertices = 2 * (# edges).
Thus complexity = O(e), if e is number of edges. (Note some vertices may never get reached, so don't have to add O(v). If also cycle through all vertices then O(v+e).)

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?

Breadth-First visits as few vertices as possible before 'backtracking' (removing a vertex from the queue). Thus neighbors of V are visited first, then neighbors of neighbors, etc.

Priority-First Traversal (Priority Queue Based)

Vertices to be visited next are put on a priority queue

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

------------------------

Algorithm called Dijkstra's algorithm finds shortest path from one node to another. Uses a "greedy" style algorithm which keeps adding vertices which are closest to start. Uses a priority queue to establish which item to consider next.

Topological sort uses depth first search:

Suppose we have a directed graph with no cycles (acyclic). Directed acyclic graph is sometimes called a DAG.

We would like to list all elements in an order which is consistent with the graph ordering. I.e., so all edges point same direction.

Can be helpful if need to perform tasks in some order and some tasks can only be accomplished after some others are done

The idea of sorting algorithm is that if we do a depth-first search, then complete a node only when all nodes reachable from it have been completed:

Do a, b, c, f, $f, d, e, $e, $d, $c, $b, $a where $ means backing up from node.

Sorted order is: a, b, c, d, e, f

Thus when return from node, add it to front of list. Then have sorted list when done:

For variety, write it in a subclass of one of graphs:

class TopoSortGraph extends DirectedMatrixGraph
{
    public void topSort()
    {
        List orderList = new SinglyLinkedList();
        for (Iterator vertexIt = elements(); vertexIt.hasMoreElements(); vertexIt.nextElement())
        {
            if (!isVisited(vertexIt.value())
                DFS(vertexIt.value(),orderList);
        }
        return orderList;
    }

    public void DFS(Object node, List orderList)
    {
        visit(node);
        for (Iterator nbrIt = neighbors(node);nbrIt.hasMoreElements; nbrIt.nextElement())
        {
            if (!isVisited(nbrIt.value()))
                DFS(nbrIt.value(),orderList);
        }
        orderList.add(node)
    }

Differs from algorithm in text in that return in order so arrows go left to right (text's version went from right to left) and wrote it as subclass of GraphMatrixDirected.

(Note can write in exactly same way so as to be subclass of GraphListDirected.)

If graph really were a tree, what order would elements end up in list?