[BGL]Why the output of algorithms are vertex sequence(PredecessorMap)? How about parallel edges??

For example, a graph has 2 nodes: A & B. There are 2 edges form A to B which are edge1 & edge2. edge1 has weight 1, edge2 has weight 2. Then the shortest path form A to B is: vertex A---edge1---vertex B. But the default output of all algorithm is vertex sequence. Why? How to get the edge sequence?? I have noticed vistor.hpp has a class edge_predecessor_recorder, but I don't know how to use it. Anybody give me a hint? -- View this message in context: http://www.nabble.com/-BGL-Why-the-output-of-algorithms-are-vertex-sequence%... Sent from the Boost - Users mailing list archive at Nabble.com.

Li Ning wrote:
For example, a graph has 2 nodes: A & B. There are 2 edges form A to B which are edge1 & edge2. edge1 has weight 1, edge2 has weight 2. Then the shortest path form A to B is: vertex A---edge1---vertex B. But the default output of all algorithm is vertex sequence. Why? How to get the edge sequence?? I have noticed vistor.hpp has a class edge_predecessor_recorder, but I don't know how to use it. Anybody give me a hint?
For the shortest path problem you can translate "edgeless" representation to "vertexless" as follows: vertexless_path translate(weight_map, pred_map, source, tail) { result := []; s := source; t := tail; while (t != s) { result += min_arg(weight_map[(pred_map[t], t)]); //Edge with the minimal weight t = pred_map[t]; } return result; } Of cause, using the edge_predecessor_recorder is a better solution. If you provide your working code I will try to modify it accordingly. Regards, Dmitry

Dmitry Bufistov wrote:
Li Ning wrote:
For example, a graph has 2 nodes: A & B. There are 2 edges form A to B which are edge1 & edge2. edge1 has weight 1, edge2 has weight 2. Then the shortest path form A to B is: vertex A---edge1---vertex B. But the default output of all algorithm is vertex sequence. Why? How to get the edge sequence?? I have noticed vistor.hpp has a class edge_predecessor_recorder, but I don't know how to use it. Anybody give me a hint?
For the shortest path problem you can translate "edgeless" representation to "vertexless" as follows:
vertexless_path translate(weight_map, pred_map, source, tail) { result := []; s := source; t := tail; while (t != s) { result += min_arg(weight_map[(pred_map[t], t)]); //Edge with the minimal weight t = pred_map[t]; } return result; }
Of cause, using the edge_predecessor_recorder is a better solution. If you provide your working code I will try to modify it accordingly.
Regards, Dmitry
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I wrote a recorder that derived from dijkstra_visitor<> and implement the
edge_relax to record the edges sequence.
template <class PredecessorVec>
class record_edge_predecessors : public dijkstra_visitor<>
{
public:
record_edge_predecessors(PredecessorVec& p)
: m_predecessor(p) { }
template

The code works...
I'm not convinced that it does. First, the predecessor map is not actually a property map - you are using it to accumulate relaxed edges. Second, the order of edges may be arbitrary and certainly not contiguous. I'm not sure I see how to efficiently recover the path using this approach.
I don't know how to use edge_predecessor_recorder, it seems unable to slove this problem, because it just has a operator().
I think it maps onto a visitor that has a tree_edge function, so its only useful for BSF, DSF, and MST visitors.
And I has some additional questions: 1. Why BGL introduce descriptor? This new thing bring what advantage? In STL, the communication between Algo & Container is iterator. But in BGL, a new "iterator-like" thing: descriptor has been introduced. What is the difference? The document says descriptor is a "handle", isn't iterator also a "handle"??
Descriptors can't "move" (++/--) and can't be dereferenced. The biggest reason for using descriptors is that they can provide a higher degree of stability than iterators. For example, a vector will invalidate all iterators on insert and remove. This makes it virtually impossible to build a relational data structure (like a graph) on top of vectors, if you use iterators (or pointers) from vertex to edge, edge to vertex, and both their properties.
2. Can descriptor convertable with iterator?
The BGL does not provide a translation between iterators and descriptors. Andrew Sutton andrew.n.sutton@gmail.com

The biggest reason for using descriptors is that they can provide a higher
degree of stability than iterators. For example, a vector will invalidate all iterators on insert and remove.
[skip]
"Remove" also invalidates vertex descriptors!
For VertexList == vecS, yes. My advice regarding this would be: If you're using vecS for vectors, don't remove vertices. If you have to remove vertices, use listS and never call num_vertices, For anything other than vecS, remove_vertex shouldn't invalidate descriptors other than the one removed. I hope. Andrew Sutton andrew.n.sutton@gmail.com

Andrew Sutton wrote:
The biggest reason for using descriptors is that they can provide a higher degree of stability than iterators. For example, a vector will invalidate all iterators on insert and remove.
[skip]
"Remove" also invalidates vertex descriptors!
For VertexList == vecS, yes. My advice regarding this would be: If you're using vecS for vectors, don't remove vertices. If you have to remove vertices, use listS and never call num_vertices,
For anything other than vecS, remove_vertex shouldn't invalidate descriptors other than the one removed. I hope.
Yes, and as I understand it, ditto iterators. So the question still stands! Louis.

"Remove" also invalidates vertex descriptors!
For VertexList == vecS, yes. My advice regarding this would be: If you're using vecS for vectors, don't remove vertices. If you have to remove vertices, use listS and never call num_vertices,
For anything other than vecS, remove_vertex shouldn't invalidate descriptors other than the one removed. I hope.
Yes, and as I understand it, ditto iterators. So the question still stands!
I can rephrase my previous answer. Descriptors provide improved stability over iterators. With vectors, iterators are invalidated on insert and erase, but descriptors are only invalidated on erase/remove. With linked memory structures (e.g,. lists and trees) neither set of operations (should) invalidate other iterators or descriptors. Andrew Sutton andrew.n.sutton@gmail.com

Andrew Sutton-2 wrote:
"Remove" also invalidates vertex descriptors!
For VertexList == vecS, yes. My advice regarding this would be: If you're using vecS for vectors, don't remove vertices. If you have to remove vertices, use listS and never call num_vertices,
For anything other than vecS, remove_vertex shouldn't invalidate descriptors other than the one removed. I hope.
Yes, and as I understand it, ditto iterators. So the question still stands!
I can rephrase my previous answer. Descriptors provide improved stability over iterators. With vectors, iterators are invalidated on insert and erase, but descriptors are only invalidated on erase/remove. With linked memory structures (e.g,. lists and trees) neither set of operations (should) invalidate other iterators or descriptors.
Andrew Sutton andrew.n.sutton@gmail.com
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I understand. The descriptor exists because of 'add_edge' like functions. And the inter-reference between vertex & edge is operated on descriptor will eliminate affect of 'add' operation. However, remove still has invalidate problem. -- View this message in context: http://www.nabble.com/-BGL-Why-the-output-of-algorithms-are-vertex-sequence%... Sent from the Boost - Users mailing list archive at Nabble.com.

Andrew Sutton-2 wrote:
The code works...
I'm not convinced that it does. First, the predecessor map is not actually a property map - you are using it to accumulate relaxed edges. Second, the order of edges may be arbitrary and certainly not contiguous. I'm not sure I see how to efficiently recover the path using this approach.
I don't know how to use edge_predecessor_recorder, it seems unable to slove this problem, because it just has a operator().
I think it maps onto a visitor that has a tree_edge function, so its only useful for BSF, DSF, and MST visitors.
And I has some additional questions: 1. Why BGL introduce descriptor? This new thing bring what advantage? In STL, the communication between Algo & Container is iterator. But in BGL, a new "iterator-like" thing: descriptor has been introduced. What is the difference? The document says descriptor is a "handle", isn't iterator also a "handle"??
Descriptors can't "move" (++/--) and can't be dereferenced. The biggest reason for using descriptors is that they can provide a higher degree of stability than iterators. For example, a vector will invalidate all iterators on insert and remove. This makes it virtually impossible to build a relational data structure (like a graph) on top of vectors, if you use iterators (or pointers) from vertex to edge, edge to vertex, and both their properties.
2. Can descriptor convertable with iterator?
The BGL does not provide a translation between iterators and descriptors.
Andrew Sutton andrew.n.sutton@gmail.com
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Is BGL provide tools to do this job? Or how to write a visitor to record this infomation? -- View this message in context: http://www.nabble.com/-BGL-Why-the-output-of-algorithms-are-vertex-sequence%... Sent from the Boost - Users mailing list archive at Nabble.com.

Li Ning wrote:
For example, a graph has 2 nodes: A & B. There are 2 edges form A to B which are edge1 & edge2. edge1 has weight 1, edge2 has weight 2. Then the shortest path form A to B is: vertex A---edge1---vertex B. But the default output of all algorithm is vertex sequence. Why? How to get the edge sequence?? I have noticed vistor.hpp has a class edge_predecessor_recorder, but I don't know how to use it. Anybody give me a hint?
Finally I have figure out how to write the recorder. Following is the codes:
template <class PredecessorMap>
class record_edge_predecessors : public dijkstra_visitor<>
{
public:
record_edge_predecessors(PredecessorMap p)
: m_predecessor(p){ }
template

Li Ning wrote:
Question remains: In above helper function, the return type is hard coded to vector<int>. Is it possible to traits out the edge_index type of a graph type G(or some type else)??
Well, it's "typename property_traits<EdgeIndexMap>::value_type" Thanks, all. -- View this message in context: http://www.nabble.com/-BGL-Why-the-output-of-algorithms-are-vertex-sequence%... Sent from the Boost - Users mailing list archive at Nabble.com.

template
std::vector<int> translate_to_edges_index(const EdgePredecessorMap& em, const VertexPredecessorMap& vm, const EdgeIndexMap& im, VertexDescriptor dest) { std::vector<int> res; while(vm[dest] != dest) { res.push_back(im[em[dest]]); dest = vm[dest]; } return res; }
I would recommend using the get() and put() functions for property maps instead of operator[]. It allows a broader class of property maps to be used with the algorithm. Andrew Sutton andrew.n.sutton@gmail.com
participants (4)
-
Andrew Sutton
-
Dmitry Bufistov
-
Li Ning
-
Louis Lavery