This preview shows pages 1–3. Sign up to view the full content.
This preview has intentionally blurred sections. Sign up to view the full version.
View Full Document
Unformatted text preview: 468 Explicit State Why does this algorithm work? Consider any two nodes a and b with a path between them: a → n 1 → n 2 → ... → n k → b (where k ≥ 0). We have to show that the final graph has an edge from a to b . The nodes n 1 through n k are encountered in some order by the algorithm. When the algorithm encounters a node n i , it “short circuits” the node, i.e., it creates a new path from a to b that avoids the node. Therefore when the algorithm has encountered all nodes, it has created a path that avoids all of them, i.e., it has an edge directly from a to b . Representing a graph To write up the algorithm as a program, we first have to choose a representation for directed graphs. Let us consider two possible representations: • The adjacency list representation. The graph is a list with elements of the form I#Ns where I identifies a node and Ns is an ordered list of its immediate successors. As we will see below, ordered lists of successors are more efficient to calculate with than unordered lists. • The matrix representation. The graph is a twodimensional array. The element with coordinates ( I , J ) is true if there is an edge from node I to node J . Otherwise, the element is false. We find that the choice of representation strongly influences what is the best computation model. In what follows, we assume that all graphs have at least one node and that the nodes are consecutive integers. We first give a declarative algorithm that uses the adjacency list representation [139]. We then give an in place stateful algorithm that uses the matrix representation [41]. We then give a second declarative algorithm that also uses the matrix representation. Finally, we compare the three algorithms. Converting between representations To make comparing the two algorithms easier, we first define routines to convert from the adjacency list representation to the matrix representation and vice versa. Here is the conversion from adjacency list to matrix: fun {L2M GL} M={Map GL fun {$ I#_} I end } L={FoldL M Min M.1} H={FoldL M Max M.1} GM={NewArray L H unit } in for I#Ns in GL do GM.I:={NewArray L H false } for J in Ns do GM.I.J:= true end end GM end Copyright c 20013 by P. Van Roy and S. Haridi. All rights reserved. 6.8 Case studies 469 fun {DeclTrans G} Xs={Map G fun {$ X#_} X end } in {FoldL Xs fun {$ InG X} SX={Succ X InG} in {Map InG fun {$ Y#SY} Y# if {Member X SY} then {Union SY SX} else SY end end } end G} end Figure 6.10: Transitive closure (first declarative version) In this routine, as in all following routines, we use GL for the adjacency list representation and GM for the matrix representation. Here is the conversion from matrix to adjacency list: fun {M2L GM} L={Array.low GM} H={Array.high GM} in for I in L..H collect:C do {C I# for J in L..H collect:D do if GM.I.J then {D J} end end } end end This uses the loop syntax including the accumulation procedure collect:C to good advantage....
View
Full
Document
This document was uploaded on 08/10/2011.
 Spring '11

Click to edit the document details