[Graph] initialize_vertex change vertex color (visitor)
Hi all, I would like to build a visitor (for dikstra) with the initialise_vertex acting as 'colour map' modifier. I want to exclude some vertices from the search based on a condition. So I want to set some vertices 'black' in the init part of the algorithm. class dijkstra_2step : public boost::default_dijkstra_visitor { public: dijkstra_2step(std::vector<Weight> dists, double threshold): distances(dists), threshold(threshold) {} // THIS PART IS NOT CORRECT!!!! // void initialize_vertex(boost::graph_traits <unGraph>::vertex_descriptor u, const unGraph& g){ if( distances[u] > threshold ) color[u] = black; // ?????? } ////////// std::vector<Weight> distances; double threshold; }; Any help for the above visitor? How to I access the colour? I couldn't find something online. Thanks
I probably need to give a bit clearer description for what I need to do. I would like to build a visitor that accesses the colour_map of a specific vertex. The idea is to 'hide' some vertices from the search completely. I have found that the possible solution might be through the 'initialize_vertex()' or do you think some other trick is better? Best On Mon, Jan 13, 2014 at 11:38 AM, The Maschine < justthemaschine@googlemail.com> wrote:
Hi all,
I would like to build a visitor (for dikstra) with the initialise_vertex acting as 'colour map' modifier. I want to exclude some vertices from the search based on a condition. So I want to set some vertices 'black' in the init part of the algorithm.
class dijkstra_2step : public boost::default_dijkstra_visitor
{
public:
dijkstra_2step(std::vector<Weight> dists, double threshold): distances(dists), threshold(threshold) {}
// THIS PART IS NOT CORRECT!!!! //
void initialize_vertex(boost::graph_traits <unGraph>::vertex_descriptor u, const unGraph& g){
if( distances[u] > threshold ) color[u] = black; // ??????
}
//////////
std::vector<Weight> distances;
double threshold;
};
Any help for the above visitor? How to I access the colour?
I couldn't find something online.
Thanks
I would like to build a visitor that accesses the colour_map of a specific vertex. The idea is to 'hide' some vertices from the search completely.
The algorithm initializes the color map to white AFTER calling
initialize_vertex. So your strategy won't work. Perhaps using filtered graph
is a better option?
If you wish to persevere with the current strategy, you could try to skip
the initialization by using the dijkstra_shortest_path_no_init function, but
be careful about also initializing the distance map and predecessor map
yourself.
Best wishes, Alex
template
Hi Alex and thanks, Filtering is not good for me as it takes a lot of time. I have done a sub-graphing(filtering) version of my code but its very slow (no need to explain why as its not related). Ill try to rethink my sub graphing version though, thanks. I have also done a version that uses an exemption when the visitor hits the limit but I believe this leaves some incomplete things.
Hi Alex and all, Do you think its possible to do something in the 'discovery' phase of the visitor/search? Can I test in the discovery of a vertex and make it 'undiscoverable'/remove it from the search queue? Any ideas? Thanks
Do you think it's possible to do something in the 'discovery' phase of
the visitor/search?
Can I test in the discovery of a vertex and make it 'undiscoverable'/remove it from the search queue?
I suppose you could do whatever you wanted to do upon the first discovery and not do it upon all subsequent discoveries. It is just not very elegant, and you'll do a "if(first)" on every discovery. Best, Alexc
Hi Alex and all, Examine Vertex vis.examine_vertex(u, g) void This is invoked on a vertex as it is popped from the queue. This happens immediately before examine_edge() is invoked on each of the out-edges of vertex u. "Examine" seems to work once on first encounter (is that correct??) so might worth a try. I did try the code below but I got errors on the part the works with the color map. Any ideas? class dijkstra_2step : public boost::default_dijkstra_visitor { public: dijkstra_2step(std::vector<Weight> dists, double threshold): distances(dists), threshold(threshold) {} void examine_vertex(boost::graph_traits <unGraph>::vertex_descriptor u, const unGraph& g){ boost::property_map< unGraph, boost::vertex_color_t >::type colorMap = boost::get(boost::vertex_color, g); if( distances[u] > threshold ) colorMap[u] = boost::color_traits::black(); } std::vector<Weight> distances; double threshold; }; Thanks
"Examine" seems to work once on first encounter (is that correct??) so might worth a try. I did try the code below but I got errors on the part the works with the
color map. Any ideas?
class dijkstra_2step : public boost::default_dijkstra_visitor { public: dijkstra_2step(std::vector<Weight> dists, double threshold): distances(dists), threshold(threshold) {}
void examine_vertex(boost::graph_traits <unGraph>::vertex_descriptor u, const unGraph& g){ boost::property_map< unGraph, boost::vertex_color_t >::type
colorMap = boost::get(boost::vertex_color, g); >> if( distances[u] > threshold ) colorMap[u] = boost::color_traits::black(); >> } >> std::vector<Weight> distances; >> double threshold; >>};
If I understand correctly, your distances vector is another one than the one
that the dijkstra_shortest_path is working on? Otherwise, it seems that this
visitor makes little sense. Upon examination the distance for all vertices
is distance_inf, because that is how they are initialized.
You may want to make better use of property maps for your visitor. Remember,
visitors are passed by value internally, you don't want to copy your
distance vector all the time. You will need to create your own color map and
pass it both to dijkstra_shortest_path and your visitor.
Beware that you cannot use the named parameter variation of
dijkstra_shortest_paths if you want to specify your own color map:
http://comments.gmane.org/gmane.comp.lib.boost.devel/206220
template
From your link seem that I am in the same category of 'no_init' search so
Thanks Alex,
Yes the m_distance in the visitor is the result of a previous search (not
the current working one).
A couple of questions.
If I use my own colour map as you describe, Could I also colour it
beforehand and not in the visitor? (the ones that are outside the cutoff
will always be outside, this will not change during search)
the colour map that I provide is used directly and its not 're-initialised'.
What Im trying to achieve is to colour some vertices black so that the
search will consider them "disconnected" and leave them with 'inf' distance.
This also means that these vertices won't be part of any later computation
inside the visitor, no relaxation etc (as an extension of what I have here:
in a 'special brandes betweenness' visitor I could, theoretically at the
moment, exclude them for the extra 'delta' calculations inside the visitor
steps).
Right? If Im missing something please let me know.
Now the code. Im having treble building the correct 'no_init' call.
Googling around helped but not much.
Any ideas? Thanks
std::vector<Vertex> predecessors(boost::num_vertices(m_ugraph));
std::vector<Weight> distances(boost::num_vertices(m_ugraph),
std::numeric_limits<double>::max() );
IndexMap indexMap = boost::get(boost::vertex_index, m_ugraph);
PredecessorMap predecessorMap(&predecessors[0], indexMap);
DistanceMap distanceMap(&distances[0], indexMap);
// What is the definition of the ColorMap if you use it outside a visitor?
typedef typename boost::property_traits<ColorMap>::value_type
color_type;
typedef typename boost::color_traits
If I use my own colour map as you describe, Could I also colour it beforehand and not in the visitor?
From your link seem that I am in the same category of 'no_init' search so
Probably the colour map that I provide is used directly and its not 're-initialised'. That would work I think.
Now the code. Im having treble building the correct 'no_init' call. Googling around helped but not much.
Avoid using pointers as property maps, sometimes that causes problems. You
could use shared_array_property_maps.
typedef boost::default_color_type Color;
typedef boost::color_traits
Hi Alex,
Im getting there, thanks for your help.
One thing that Im getting problems is the definition of the ColorMap.
typedef boost::default_color_type Color;
typedef boost::color_traits<Color> color_traits;
typedef boost::shared_array_property_map<Color> ColorMap;
ColorMap colorMap(boost::num_vertices(m_ugraph), indexMap);
###
error: wrong number of template arguments (1, should be 2)
In file included from /usr/include/boost/graph/named_function_params.hpp:25:0,
from /usr/include/boost/graph/breadth_first_search.hpp:23,
from ../graph.h:22,
from ../graph.cpp:1:
/usr/include/boost/property_map/shared_array_property_map.hpp:19:7:
error: provided for 'template
::vertex_descriptor&, Color&)'
###
From:The Maschine Im getting there, thanks for your help.
One thing that Im getting problems is the definition of the ColorMap.
typedef boost::shared_array_property_map<Color> ColorMap; ColorMap colorMap(boost::num_vertices(m_ugraph), indexMap); ...
error: wrong number of template arguments (1, should be 2)
My fault for not trying it out.
How about:
typedef boost::property_map
Yes! thanks! That second argument at the array was the problem. If you are ever around central London Ill be happy to buy you a beer for all your help!
participants (3)
-
alex
-
Alex
-
The Maschine