[BGL] Having a cost function as weight map
Hi,
I can't find how to do this pretty basic thing : having a function
instead of a field to compute the cost of edges for various path finding
algorithms. I couldn't find the answer in the documentation and Google
was of no help. Did I miss something obvious ?
Example :
-------------------
#include
On Fri, 18 Dec 2009, Maxime van Noppen wrote:
Hi,
I can't find how to do this pretty basic thing : having a function instead of a field to compute the cost of edges for various path finding algorithms. I couldn't find the answer in the documentation and Google was of no help. Did I miss something obvious ?
Example :
------------------- #include
#include #include struct my_edge { double cost() const { return cost_ * 2; } double cost_; };
struct my_node { };
int main() { typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, my_node, my_edge > graph_t; typedef boost::graph_traits
::vertex_descriptor vertex_t; graph_t graph;
vertex_t v /*= ... */;
using boost::weight_map;
// Works : boost::dijkstra_shortest_paths(graph, v, weight_map(boost::get(&my_edge::cost_, graph)));
// Doesn't compile : //boost::dijkstra_shortest_paths(graph, v, // weight_map(boost::get(&my_edge::cost, graph))); } -------------------
Thanks !
It looks like there is no property map that does what you want, although
there should be. Try something like this (not tested); it assumes that
your functors are lightweight to copy, have a const operator()(), and do
not have any internal state:
#include
Jeremiah Willcock wrote:
Please tell me if there are any problems, as I have not tested this.
It seems to work. I had to do a little fix to your code though. In the
function_property_map you use 'value_type' which isn't defined and which
is, I believe :
typedef typename boost::property_traits<
function_property_map
On Fri, 18 Dec 2009, Maxime van Noppen wrote:
Jeremiah Willcock wrote:
Please tell me if there are any problems, as I have not tested this.
It seems to work. I had to do a little fix to your code though. In the function_property_map you use 'value_type' which isn't defined and which is, I believe :
typedef typename boost::property_traits< function_property_map
>::value_type value_type;
OK. It actually should be "typename boost::result_of
I also changed the functor type from 'Functor' to 'const Functor&'. It seems to work. What was the rationale for copying it ?
In case your operator()() in the functor is non-const (even though I said I was assuming it was const); switching to a reference is fine.
My functor needs to have a pointer/reference to the graph to be able to get the my_edge object from the edge_descriptor passed to the operator().
OK. Did it work otherwise? -- Jeremiah Willcock
Jeremiah Willcock wrote:
OK. It actually should be "typename boost::result_of
::type" like what is in the specialization of property_traits.
Ok fixed it.
In case your operator()() in the functor is non-const (even though I said I was assuming it was const); switching to a reference is fine.
And to a const reference ? My operator() is const.
OK. Did it work otherwise?
I didn't test it on a real world test case yet but I added a std::cout in my functor's operator() and it is called, so I'd say yes. -- Maxime
On Fri, 18 Dec 2009, Maxime van Noppen wrote:
Jeremiah Willcock wrote:
OK. It actually should be "typename boost::result_of
::type" like what is in the specialization of property_traits. Ok fixed it.
In case your operator()() in the functor is non-const (even though I said I was assuming it was const); switching to a reference is fine.
And to a const reference ? My operator() is const.
That's what I meant.
OK. Did it work otherwise?
I didn't test it on a real world test case yet but I added a std::cout in my functor's operator() and it is called, so I'd say yes.
OK. I just wanted to make sure there weren't any other obvious errors in the code. -- Jeremiah Willcock
I'd like to add, as a future reference, that this approach works well when the bundled property is a pointer. An example could be when you have many graphs with the same underlying vertex set and different edges, so you might want to use pointers to VertexProperty objects as bundled properties. In particular, VertexProperty could contain a field to be used as the vertex index. See, for example http://pastebin.com/6zpwCb4X for such an object (in the example we don't use pointers, though). In this case we can still use algorithms such as r_c_shortest_paths that expect an index map by adding value_type operator[](const Arg& arg) const { return f(arg); } to function_property_map as posted by Jeremiah and edited by Maxime. -- View this message in context: http://boost.2283326.n4.nabble.com/BGL-Having-a-cost-function-as-weight-map-... Sent from the Boost - Users mailing list archive at Nabble.com.
On Thu, 5 Sep 2013, potato_research wrote:
I'd like to add, as a future reference, that this approach works well when the bundled property is a pointer. An example could be when you have many graphs with the same underlying vertex set and different edges, so you might want to use pointers to VertexProperty objects as bundled properties.
In particular, VertexProperty could contain a field to be used as the vertex index. See, for example http://pastebin.com/6zpwCb4X for such an object (in the example we don't use pointers, though). In this case we can still use algorithms such as r_c_shortest_paths that expect an index map by adding
value_type operator[](const Arg& arg) const { return f(arg); }
to function_property_map as posted by Jeremiah and edited by Maxime.
Is that something that should be changed in Boost itself? -- Jeremiah Willcock
It just wanted to be a note for someone who, like me, will stumble upon this thread with the same problem. Nothing to change in Boost! :) -- View this message in context: http://boost.2283326.n4.nabble.com/BGL-Having-a-cost-function-as-weight-map-... Sent from the Boost - Users mailing list archive at Nabble.com.
participants (4)
-
Jeremiah Willcock
-
Jeremiah Willcock
-
Maxime van Noppen
-
potato_research