Traversing graphs

Thomas Lindgren thomasl_erlang@REDACTED
Fri May 27 15:41:03 CEST 2005


--- Vlad Dumitrescu <vlad_dumitrescu@REDACTED>
wrote:
> From: "Vladimir Sekissov" <svg@REDACTED>
> > May be it could be easier with
> continuation-passing style
> 
> Yes, that's a good idea. I will look at it.
> 
> Maybe my main problem is that I try to wite a
> general mapfold-like function,
> when it would be easier to do it in several steps.
> For example first mark
> some nodes with attributes, then transform the graph
> according to the
> markings.

That is, in my experience, often a good idea. (You can
usually mangle the code later if it turns out to be
costly.)

When working with graphs, the primary problem is
representation IMO. I work with small or medium-sized
graphs (usually 100-1000 nodes or so) and like using
functional representations (no ets tables), so it's
usually dictionaries mapping 
 (NodeName -> [Successor]) 
or the equivalent.

When speed is desired, using a tuple with node name =
argument position can be fast enough. (This is
essentially just representing the graph as a vector.
You can split the vector into several ones too, e.g.,
one vector for predecessors, one for successors, one
for content.)

(Note that element/2 on a tuple should be faster than
doing an ets hash lookup too.)

Writing graph programs:

- consider writing higher-order functions on graphs

- if using a functional representation, batch requests
and rebuild the graph afterwards. For sane debugging,
it might be a good idea regardless of representation
:-)

- you will usually need a set of "already-visited"
nodes when doing a traversal; pass this as a
parameter. Here is a depth-first traversal that
transforms a state as it goes along:

traverse(Node, State, Visited, Graph) ->
  case visited(Node, Visited) of
    true ->
       {State, Visited};
    false ->
       Ns = successors(Node, Graph),
       NewVisited = visit(Node, Visited),
       NewState = transform_state(Node, Graph, State),
       traverse_all(Ns, NewState, NewVisited, Graph)
  end.

assuming appropriate implementations of the
operations.

- I have also found the following to be a practical
idiom: have functions to list the graph nodes in
useful orders, then use that list to fold some
operation over the graph.

- encapsulate the graph representation as an ADT, so
that you can at least somewhat easily change
representations. (I haven't found a useful "generic"
ADT for graphs, since some representations need more
managing than others, but you can at least reduce the
pain.)

Best,
Thomas



		
__________________________________ 
Yahoo! Mail 
Stay connected, organized, and protected. Take the tour: 
http://tour.mail.yahoo.com/mailtour.html 




More information about the erlang-questions mailing list