Lecture 23: Graphs and Backtracking



  1. Reading: TSS, chapter 11
  2. What are graphs? Here is a small, simple graph:
    A graph is like a road-map. The black circles are cities. The arrows are roads. We think of all roads as one-way roads, and indicate that with arrows.

    An alternative representation of the graph: the nodes are intersections in a city, the arrows are one-way streets; the nodes are stations in a hospital, the arrows are ways to move a patient from one station to another; the nodes are pipeline joints, the arrows are pipelines, etc.

    A Scheme representation:

    (define Graph 
      '((A (B E))
        (B (E F))
        (C (D))
        (D ())
        (E (C F))
        (F (D G))
        (G ())))
    
    In other words, we form a list of city-neighbor pairs.

    Task: Formulate a data definition. "A node is a symbol." And "A graph is ..."

  3. We want to compute many things on graphs. For example, we would like to sort them in a topological manner. That is often helpful for scheduling tasks in a graph (e.g. work on patients).

    Topological Sort: produce a list of nodes from a graph such that if Node_i is listed before Node_j, Node_i cannot be reached from Node_j.

    Work through the example: one result is

      (list 'D 'G 'C 'F 'B 'E 'A)
    

    How can we do this? A graph consists of a universe of nodes Nodes and a bunch of edges Edges. Assume the program consumes the list of nodes and the graph (see above for representation):

    #|
      top-sort : (listof node) graph -> (listof node)
      (define (lo-nodes a-graph) ...)
    
      Purpose: produce a list with all items on lo-nodes, but in topological
       order according to a-graph
    
      Example: (list 'A 'B 'C 'D 'E 'F 'G) and Graph might produce
       (list 'D 'G 'C 'F 'B 'E 'A)
       or
       (list 'G 'D 'C 'F 'E 'B 'A)
       or
       ...
    |#
    

    Task: try to think of a generative step (in English)

    Hint:

    Important: all-those-nodes-in-Nodes-that-have-no-incoming-edges 
    
    Step: (top-sort (subtract Nodes all-those-nodes-in-Nodes-that-have-no-incoming-edges) Graph)
    


  4. Something else we might wish to compute is a route from some node origination to a node destination.

    Examples:

    1. from B to G: B, F, G
    2. from D to D: D
    3. from E to D: either E, C, D or E, F, D
    4. from C to G: there is no route

    Let's do a data analysis: a graph is represented as above. A destination is a symbol, and so is an origination. A route is a (listof node) or #f. What does #f indicate? The lack of a route.

    So here are a contract and header:

    #|
       find-route : node node graph -> (union (listof node) #f)
       (define (find-route origination destination graph) ...)
    
       Purpose: produce a list of nodes, starting with origination and
         ending in destination, that takes us from the former to the latter
         in graph
    
       Examples: see above and repeat
    |#
    

    Task: When is the problem trivially solvable? What is the result in that case?
    When origination and destination are the same, the route is trivial: (list destination)

    Task: How do we generate the next problem? Is there just one possible next problem?
    We consider the neighboring nodes. That's a whole list. Then we try one at a time -- with an auxiliary function.
    Time to do the first function:

    (define (find-route O D graph)
      (printf "(find-route ~s ~s)~n" O D)
      (cond
        ((eq? O D) (list D))
        (else (local ((define route (try-all-neighbors (neighbors O graph) D graph)))
    	    (cond
    	      ((boolean? route) #f)
    	      (else (cons O route)))))))
    

    If it works and returns a list, we are done. If not, we continue to try. If there are no neighbors (as in D or G) or if we can't reach the destination from any neighbor, we exhaust the list and return #f.
    Time for try-all-neighbors
    (define (try-all-neighbors lo-Os D graph)
      (cond
        ((empty? lo-Os) #f)
        (else (local ((define route (find-route (first lo-Os) D graph)))
    	    (cond
    	      ((boolean? route) (try-all-neighbors (rest lo-Os) D graph))
    	      (else route))))))
    

    Homework: develop (neighbors: node graph -> (listof node))




Matthias Felleisen This page was generated on Fri Apr 9 09:17:38 CDT 1999.