Boost logo

Boost :

From: David Abrahams (abrahams_at_[hidden])
Date: 2000-08-29 00:53:22


In 1.2.6 you write:

   The job of recording the predecessors is quite simple. When Dijkstra's
   algorithm adds an edge to the shortest-paths tree we just record the
   source vertex as the parent of the target vertex. Here we use the put()
   function associated with the property accessor to record the
   predecessor. The category of the visitor tells the algorithm when to
   invoke the process() method. In this case we only want to be notified
   about edges in the shortest-paths tree so we specify tree_edge_tag.

        template <class Predecessor>
        class predecessor_visitor
        {
          ...
          typedef tree_edge_tag category;

          template <class Edge, class Graph>
          void process(Edge e, Graph& g) {
            put(_p, target(e, g), source(e, g));
          }
          ...
        };

Even looking at the associated code, this passage is very confusing. Most of
it centers around the put() function:

 1. In what way is it "associated with the property accessor"? If
    overloading is the mechanism at work here, you need to tell us so.

 2. What the heck is it doing? After some careful thought, I can guess that
it
    is setting the predecessor property of the node specified by the
    expression "target(e, g)" to be the result of "source(e, g)".

 3. I also speculate that the category of a visitor acts as a filter which
    determines when it is invoked, and there must be some very special
    categories which are specific to particular algorithms and kinds of
    graph traversal (?)

 4. I know that a visitor normally has a bunch of different functions, but
    I'd like to know why we're implementing the one called "process" as
    opposed to any of the others at this point.

On the basis of my speculation, I suggest some radical name changes:

 1. Rename "property accessor" to "property tag", "property reference", or
    probably best of all, simply "property". I know there were long
    discussions about this in the past, but consider: the way the usage
    above looks, the property accessor isn't really doing any accessing at
    all. Instead, it is the put() function which accesses the property.

 2. Rename "put()" to "set()". The code above seems to be setting the
    predecessor property of the target node.

 3. Rename "category" to "filter" (or something). At least if I've
    understood your categories properly, they don't mirror categories as
we've seen
    them for iterators and containers (describing capabilities).

 4. Rename "tree_edge_tag" to something which better describes its function,
    like "minimum_cost_path_filter".

You continue:

   As a finishing touch we create a helper function to make it more
   convenient to create predecessor visitors. All GGCL visitors have a
   helper function like this.

           template <class Predecessor>
           predecessor_visitor<Predecessor>
           visit_predecessor(Predecessor p) {
              return predecessor_visitor<Predecessor>(p);
           }

So, does this function "visit a predecessor", or make an object which does
so? If I've understood things, the answer is no. Instead, I think it makes
an object which sets the "predecessor in a shortest path" property. So it
should be called something like "label_shortest_path".

...onward...


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk