Q: Graphs. Sorting edges. Possible? How to?
Hello.
I a newbie in BGL and I rewrite my LEDA code now...
I have to sort (order) edges according to some functor.
For example (simplified):
typedef adjacency_list
Hi Stas,
The edge_iterator's of the BGL are read only. You can not reorder the
graph through the iterators.
By using a custom container (use a std::set with your custom comparison
function) for the EdgeList type, you can get the out-edges of each vertex
sorted, but there currently is not a way to get the entire edge list
sorted.
People keep asking about this... I need to look into providing better
support for this. Or if someone else wants to look into this, we'd all be
grateful.
Cheers,
Jeremy
On Tue, 18 Jun 2002, stas_fomin wrote:
stas_f> Hello.
stas_f> I a newbie in BGL and I rewrite my LEDA code now...
stas_f>
stas_f> I have to sort (order) edges according to some functor.
stas_f>
stas_f> For example (simplified):
stas_f>
stas_f> typedef adjacency_list
The edge_iterator's of the BGL are read only. You can not reorder
Thank you, Jeremy. the
graph through the iterators.
It is annoys me. Reordering edges will be very useful, for example, reordering edges in planar graph (according to some planar layout) for (re)computing faces...
By using a custom container (use a std::set with your custom comparison function) for the EdgeList type, you can get the out-edges of each vertex sorted, but there currently is not a way to get the entire edge list sorted. Ok... But BGL docs is less understandable (in comparison with LEDAbook) for me (I know I am stupid).
So, please, show me small example of declaration of some graph with out_edges sorted according to some function... I would be be very grateful. Regards, Stas.
On Wed, 19 Jun 2002, stas_fomin wrote:
stas_f> > By using a custom container (use a std::set with your custom
stas_f> comparison
stas_f> > function) for the EdgeList type, you can get the out-edges of each
stas_f> vertex
stas_f> > sorted, but there currently is not a way to get the entire edge list
stas_f> > sorted.
stas_f> Ok... But BGL docs is less understandable (in comparison with
stas_f> LEDAbook) for me (I know I am stupid).
Have you tried reading the BGL book?
stas_f> So, please, show me small example of declaration
stas_f> of some graph with out_edges sorted according to some function...
Here you go. Also, this example is checked into the libs/graph/example/
directory.
#include
On Wed, 19 Jun 2002, stas_fomin wrote: stas_f> > By using a custom container (use a std::set with your custom stas_f> comparison stas_f> > function) for the EdgeList type, you can get the out- edges of each stas_f> vertex stas_f> > sorted, but there currently is not a way to get the entire edge list stas_f> > sorted. stas_f> Ok... But BGL docs is less understandable (in comparison with stas_f> LEDAbook) for me (I know I am stupid).
Have you tried reading the BGL book?
stas_f> So, please, show me small example of declaration stas_f> of some graph with out_edges sorted according to some function...
Here you go. Also, this example is checked into the
Hi,
This answer (from Jeremy) is EXACTLY what I want! Sadly though I
am 'compilationally challenged' i.e. Visual C++ .NET chokes on it! I
don't understand the workaround in the header files enough to get it
working for me. Can anyone give me a clue about how to make the same
idea work in VC++.
Thanks - Richard Howells (LoopyLozzysDad at yahoo dot com)
--- In Boost-Users@y..., Jeremy Siek
directory.
#include
#include <iostream> #include <functional> #include <string> #include
#include /* Sample output:
0 --chandler--> 1 --joe--> 1 1 --chandler--> 0 --joe--> 0 --curly--> 2 --dick--> 3 -- dick--> 3 2 --curly--> 1 --tom--> 4 3 --dick--> 1 --dick--> 1 --harry--> 4 4 --tom--> 2 --harry--> 3
name(0,1) = chandler
name(0,1) = chandler name(0,1) = joe
*/
template <class StoredEdge> struct order_by_name : public std::binary_function
{ bool operator()(const StoredEdge& e1, const StoredEdge& e2) const { // Order by target vertex, then by name. // std::pair's operator< does a nice job of implementing // lexicographical compare on tuples. return std::make_pair(e1.get_target(), boost::get (boost::edge_name, e1)) < std::make_pair(e2.get_target(), boost::get (boost::edge_name, e2)); } }; struct ordered_set_by_nameS { }; #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION namespace boost { template <class ValueType> struct container_gen
{ typedef std::multiset type; }; template <> struct parallel_edge_traits { typedef allow_parallel_edge_tag type; }; } #endif int main() { #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION std::cout << "This program requires partial specialization" << std::endl; #else using namespace boost; typedef property EdgeProperty; typedef adjacency_list graph_type; graph_type g; add_edge(0, 1, EdgeProperty("joe"), g); add_edge(1, 2, EdgeProperty("curly"), g); add_edge(1, 3, EdgeProperty("dick"), g); add_edge(1, 3, EdgeProperty("dick"), g); add_edge(2, 4, EdgeProperty("tom"), g); add_edge(3, 4, EdgeProperty("harry"), g); add_edge(0, 1, EdgeProperty("chandler"), g);
property_map
::type id = get (vertex_index, g); property_map ::type name = get(edge_name, g); graph_traits
::vertex_iterator i, end; graph_traits ::out_edge_iterator ei, edge_end; for (boost::tie(i, end) = vertices(g); i != end; ++i) { std::cout << id[*i] << " "; for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei) std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " "; std::cout << std::endl; } std::cout << std::endl; bool found; typedef graph_traits
Traits; Traits::edge_descriptor e; Traits::out_edge_iterator e_first, e_last; tie(e, found) = edge(0, 1, g); if (found) std::cout << "name(0,1) = " << name[e] << std::endl; else std::cout << "not found" << std::endl; std::cout << std::endl;
tie(e_first, e_last) = edge_range(0, 1, g); while (e_first != e_last) std::cout << "name(0,1) = " << name[*e_first++] << std::endl; #endif return 0; }
-------------------------------------------------------------------- -- Jeremy Siek http://php.indiana.edu/~jsiek/ Ph.D. Student, Indiana Univ. B'ton email: jsiek@o... C++ Booster (http://www.boost.org) office phone: (812) 855-3608 -------------------------------------------------------------------- --
Hi,
This answer (from Jeremy) is EXACTLY what I want! Sadly though I am 'compilationally challenged' i.e. Visual C++ .NET chokes on it! I don't understand the workaround in the header files enough to get it working for me. Can anyone give me a clue about how to make the same idea work in VC++.
Thanks - Richard Howells (LoopyLozzysDad at yahoo dot com)
On Wed, 19 Jun 2002, stas_fomin wrote: stas_f> > By using a custom container (use a std::set with your custom stas_f> comparison stas_f> > function) for the EdgeList type, you can get the out- edges of each stas_f> vertex stas_f> > sorted, but there currently is not a way to get the entire edge list stas_f> > sorted. stas_f> Ok... But BGL docs is less understandable (in comparison with stas_f> LEDAbook) for me (I know I am stupid).
Have you tried reading the BGL book?
stas_f> So, please, show me small example of declaration stas_f> of some graph with out_edges sorted according to some function...
Here you go. Also, this example is checked into the
--- In Boost-Users@y..., Jeremy Siek
wrote: libs/graph/example/ directory.
#include
#include <iostream> #include <functional> #include <string> #include
#include /* Sample output:
0 --chandler--> 1 --joe--> 1 1 --chandler--> 0 --joe--> 0 --curly--> 2 --dick--> 3 -
Hi,
I did work out the answer to my own question. I can't explain how/why
this works but by copying from the header files I ended up with the
following changes to Jeremy's posted code...[1]
Good luck if you want it - please don't ask me to explain it!
Richard
[1]
Comment out from original ....
//struct ordered_set_by_nameS { };
//#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//namespace boost {
// template <class ValueType>
//struct container_gen
dick-->
3 2 --curly--> 1 --tom--> 4 3 --dick--> 1 --dick--> 1 --harry--> 4 4 --tom--> 2 --harry--> 3
name(0,1) = chandler
name(0,1) = chandler name(0,1) = joe
*/
template <class StoredEdge> struct order_by_name : public std::binary_function
{ bool operator()(const StoredEdge& e1, const StoredEdge& e2) const { // Order by target vertex, then by name. // std::pair's operator< does a nice job of implementing // lexicographical compare on tuples. return std::make_pair(e1.get_target(), boost::get (boost::edge_name, e1)) < std::make_pair(e2.get_target(), boost::get (boost::edge_name, e2)); } }; struct ordered_set_by_nameS { }; #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION namespace boost { template <class ValueType> struct container_gen
{ typedef std::multiset type; }; template <> struct parallel_edge_traits { typedef allow_parallel_edge_tag type; }; } #endif int main() { #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION std::cout << "This program requires partial specialization" << std::endl; #else using namespace boost; typedef property EdgeProperty; typedef adjacency_list graph_type; graph_type g; add_edge(0, 1, EdgeProperty("joe"), g); add_edge(1, 2, EdgeProperty("curly"), g); add_edge(1, 3, EdgeProperty("dick"), g); add_edge(1, 3, EdgeProperty("dick"), g); add_edge(2, 4, EdgeProperty("tom"), g); add_edge(3, 4, EdgeProperty("harry"), g); add_edge(0, 1, EdgeProperty("chandler"), g);
property_map
::type id = get (vertex_index, g); property_map ::type name = get (edge_name, g); graph_traits
::vertex_iterator i, end; graph_traits ::out_edge_iterator ei, edge_end; for (boost::tie(i, end) = vertices(g); i != end; ++i) { std::cout << id[*i] << " "; for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei) std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " "; std::cout << std::endl; } std::cout << std::endl; bool found; typedef graph_traits
Traits; Traits::edge_descriptor e; Traits::out_edge_iterator e_first, e_last; tie(e, found) = edge(0, 1, g); if (found) std::cout << "name(0,1) = " << name[e] << std::endl; else std::cout << "not found" << std::endl; std::cout << std::endl;
tie(e_first, e_last) = edge_range(0, 1, g); while (e_first != e_last) std::cout << "name(0,1) = " << name[*e_first++] << std::endl; #endif return 0; }
------------------------------------------------------------------ -- -- Jeremy Siek http://php.indiana.edu/~jsiek/ Ph.D. Student, Indiana Univ. B'ton email: jsiek@o... C++ Booster (http://www.boost.org) office phone: (812) 855-3608 ------------------------------------------------------------------ -- --
Hi Richard,
On Wed, 6 Nov 2002, loopylozzysdad wrote:
Richar> Hi,
Richar>
Richar> I did work out the answer to my own question. I can't explain
Richar> how/why this works but by copying from the header files I ended up
Richar> with the following changes to Jeremy's posted code...[1]
Richar> Good luck if you want it - please don't ask me to explain it!
I can explain it :)
As hinted by the #ifndef, the commented out version of container_gen uses
partial specialization. The first parameter to container_gen is
specialized, but the second is left as a template. Partial spec. is not
yet supported by VC++ (but soon will be).
The change you made is one of the classic ways of replacing partial
specialization with full specialization. You remove the unspecialized
parameter, and instead add a nested class template (here it is bind_).
Cheers,
Jeremy
Richar> Richard
Richar>
Richar>
Richar> [1]
Richar> Comment out from original ....
Richar> //struct ordered_set_by_nameS { };
Richar>
Richar> //#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Richar> //namespace boost {
Richar> // template <class ValueType>
Richar> //struct container_gen
On Tue, 18 Jun 2002, Jeremy Siek wrote: jsiek> By using a custom container (use a std::set with your custom comparison jsiek> function) for the EdgeList type, you can get the out-edges of each vertex jsiek> sorted, but there currently is not a way to get the entire edge list jsiek> sorted. I just realized that I'm probably wrong about the second part of the above statement. I think you can get the whole edge list sorted via a similar approach as the out-edges. I recently added a 7th template paramter to adjacency_list, which makes it possible to customize the edge-list container. Cheers, Jeremy ---------------------------------------------------------------------- Jeremy Siek http://php.indiana.edu/~jsiek/ Ph.D. Student, Indiana Univ. B'ton email: jsiek@osl.iu.edu C++ Booster (http://www.boost.org) office phone: (812) 855-3608 ----------------------------------------------------------------------
participants (4)
-
Jeremy Siek
-
loopylozzysdad
-
loopylozzysdad
-
stas_fomin