18.04.2013 Views

The.Algorithm.Design.Manual.Springer-Verlag.1998

The.Algorithm.Design.Manual.Springer-Verlag.1998

The.Algorithm.Design.Manual.Springer-Verlag.1998

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Graph Data Structures<br />

the associated bipartite graph.<br />

Special efforts must be taken to represent very large graphs efficiently. However, interesting problems<br />

have been solved on graphs with millions of edges and vertices. <strong>The</strong> first step is to make your data<br />

structure as lean as possible, by packing your adjacency matrix as a bit vector (see Section ) or<br />

removing extra pointers from your adjacency list representation. For example, in a static graph (no edge<br />

insertions or deletions) each edge list can be replaced by a packed array of vertex identifiers, thus<br />

eliminating pointers and saving potentially half the space.<br />

At some point it may become necessary to switch to a hierarchical representation of the graph, where the<br />

vertices are clustered into subgraphs that are compressed into single vertices. Two approaches exist for<br />

making such a hierarchical decomposition. <strong>The</strong> first breaks things into components in a natural or<br />

application-specific way. For example, knowing that your graph is a map of roads and cities suggests a<br />

natural decomposition - partition the map into districts, towns, counties, and states. <strong>The</strong> other approach<br />

runs a graph partition algorithm as in Section . If you are performing the decomposition for space or<br />

paging reasons, a natural decomposition will likely do a better job than some naive heuristic for an NPcomplete<br />

problem. Further, if your graph is really unmanageably large, you cannot afford to do a very<br />

good job of algorithmically partitioning it. You should first verify that standard data structures fail on<br />

your problem before attempting such heroic measures.<br />

Implementations: LEDA (see Section ) provides the best implemented graph data type currently<br />

available in C++. If at all possible, you should use it. If not, you should at least study the methods it<br />

provides for graph manipulation, so as to see how the right level of abstract graph type makes<br />

implementing algorithms very clean and easy. Although a general graph implementation like LEDA<br />

may be 2 to 5 times slower and considerably less space efficient than a stripped-down special-purpose<br />

implementation, you have to be a pretty good programmer to realize this performance improvement.<br />

Further, this speed is likely to come at the expense of simplicity and clarity.<br />

GraphEd [Him94], written in C by Michael Himsolt, is a powerful graph editor that provides an interface<br />

for application modules and a wide variety of graph algorithms. If your application demands interaction<br />

and visualization more than sophisticated algorithmics, GraphEd might be the right place to start,<br />

although it can be buggy. GraphEd can be obtained by anonymous ftp from forwiss.uni-passau.de<br />

(132.231.20.10) in directory /pub/local/graphed. See Section for more details on GraphEd and other<br />

graph drawing systems.<br />

<strong>The</strong> Stanford Graphbase (see Section ) provides a simple but flexible graph data structure in CWEB, a<br />

literate version of the C language. It is instructive to see what Knuth does and does not place in his basic<br />

data structure, although we recommend LEDA as a better basis for further development.<br />

LINK is an environment for combinatorial computing that provides special support for hypergraphs,<br />

file:///E|/BOOK/BOOK3/NODE132.HTM (3 of 5) [19/1/2003 1:30:08]

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!