Boost-Geometry-Utils
view release on metacpan or search on metacpan
src/boost/graph/distributed/crauser_et_al_shortest_paths.hpp view on Meta::CPAN
const MinInWeightMap& min_in_weight)
: inherited(boost::graph::parallel::process_group(g), get(vertex_owner, g)),
dist_queue(num_vertices(g),
dist_queue_compare_type(distance_map, compare),
id),
out_queue(num_vertices(g),
out_queue_compare_type(distance_map, min_out_weight,
combine, compare),
id),
in_queue(num_vertices(g),
in_queue_compare_type(distance_map, min_in_weight,
combine, compare),
id),
g(g),
distance_map(distance_map),
predecessor_map(predecessor_map),
min_out_weight(min_out_weight),
min_in_weight(min_in_weight),
min_distance(0),
min_out_distance(0)
#ifdef PBGL_ACCOUNTING
, local_deletions(0)
#endif
{ }
void push(const value_type& x)
{
msg_value_type msg_value =
msg_value_creator::create(get(distance_map, x),
predecessor_value(get(predecessor_map, x)));
inherited::update(x, msg_value);
}
void update(const value_type& x) { push(x); }
void pop()
{
// Remove from distance queue
dist_queue.remove(top_vertex);
// Remove from OUT queue
out_queue.remove(top_vertex);
// Remove from IN queue
in_queue.remove(top_vertex);
#ifdef PBGL_ACCOUNTING
++local_deletions;
#endif
}
vertex_descriptor& top() { return top_vertex; }
const vertex_descriptor& top() const { return top_vertex; }
bool empty()
{
inherited::collect();
// If there are no suitable messages, wait until we get something
while (!has_suitable_vertex()) {
if (do_synchronize()) return true;
}
// Return true only if nobody has any messages; false if we
// have suitable messages
return false;
}
bool do_synchronize()
{
using boost::parallel::all_reduce;
using boost::parallel::minimum;
inherited::synchronize();
// TBD: could use combine here, but then we need to stop using
// minimum<distance_type>() as the function object.
distance_type local_distances[2];
local_distances[0] =
dist_queue.empty()? (std::numeric_limits<distance_type>::max)()
: get(distance_map, dist_queue.top());
local_distances[1] =
out_queue.empty()? (std::numeric_limits<distance_type>::max)()
: (get(distance_map, out_queue.top())
+ get(min_out_weight, out_queue.top()));
distance_type distances[2];
all_reduce(this->process_group, local_distances, local_distances + 2,
distances, minimum<distance_type>());
min_distance = distances[0];
min_out_distance = distances[1];
#ifdef PBGL_ACCOUNTING
std::size_t deletions = 0;
all_reduce(this->process_group, &local_deletions, &local_deletions + 1,
&deletions, std::plus<std::size_t>());
if (process_id(this->process_group) == 0) {
crauser_et_al_shortest_paths_stats.deleted_vertices.push_back(deletions);
}
local_deletions = 0;
BOOST_ASSERT(deletions > 0);
#endif
return min_distance == (std::numeric_limits<distance_type>::max)();
}
private:
vertex_descriptor predecessor_value(vertex_descriptor v) const
{ return v; }
vertex_descriptor
predecessor_value(property_traits<dummy_property_map>::reference) const
{ return graph_traits<Graph>::null_vertex(); }
bool has_suitable_vertex() const
{
if (!dist_queue.empty()) {
top_vertex = dist_queue.top();
if (get(distance_map, dist_queue.top()) <= min_out_distance)
return true;
}
if (!in_queue.empty()) {
top_vertex = in_queue.top();
return (get(distance_map, top_vertex)
- get(min_in_weight, top_vertex)) <= min_distance;
}
return false;
}
public:
void
receive_update(process_id_type source, vertex_descriptor vertex,
src/boost/graph/distributed/crauser_et_al_shortest_paths.hpp view on Meta::CPAN
in_queue.push(vertex);
}
else {
dist_queue.update(vertex);
out_queue.update(vertex);
in_queue.update(vertex);
}
}
}
void
receive_update(process_id_type source, vertex_descriptor vertex,
std::pair<distance_type, vertex_descriptor> p)
{
if (p.first <= get(distance_map, vertex)) {
put(predecessor_map, vertex, p.second);
receive_update(source, vertex, p.first);
}
}
private:
dist_queue_type dist_queue;
out_queue_type out_queue;
in_queue_type in_queue;
mutable value_type top_vertex;
const Graph& g;
DistanceMap distance_map;
PredecessorMap predecessor_map;
MinOutWeightMap min_out_weight;
MinInWeightMap min_in_weight;
distance_type min_distance;
distance_type min_out_distance;
#ifdef PBGL_ACCOUNTING
std::size_t local_deletions;
#endif
};
/************************************************************************/
/************************************************************************
* Initialize the property map that contains the minimum incoming edge *
* weight for each vertex. There are separate implementations for *
* directed, bidirectional, and undirected graph. *
************************************************************************/
template<typename Graph, typename MinInWeightMap, typename WeightMap,
typename Inf, typename Compare>
void
initialize_min_in_weights(const Graph& g, MinInWeightMap min_in_weight,
WeightMap weight, Inf inf, Compare compare,
directed_tag, incidence_graph_tag)
{
// Send minimum weights off to the owners
set_property_map_role(vertex_distance, min_in_weight);
BGL_FORALL_VERTICES_T(v, g, Graph) {
BGL_FORALL_OUTEDGES_T(v, e, g, Graph) {
if (get(weight, e) < get(min_in_weight, target(e, g)))
put(min_in_weight, target(e, g), get(weight, e));
}
}
using boost::graph::parallel::process_group;
synchronize(process_group(g));
// Replace any infinities with zeros
BGL_FORALL_VERTICES_T(v, g, Graph) {
if (get(min_in_weight, v) == inf) put(min_in_weight, v, 0);
}
}
template<typename Graph, typename MinInWeightMap, typename WeightMap,
typename Inf, typename Compare>
void
initialize_min_in_weights(const Graph& g, MinInWeightMap min_in_weight,
WeightMap weight, Inf inf, Compare compare,
directed_tag, bidirectional_graph_tag)
{
#if 0
typename property_map<Graph, vertex_local_t>::const_type
local = get(vertex_local, g);
// This code assumes that the properties of the in-edges are
// available locally. This is not necessarily the case, so don't
// do this yet.
set_property_map_role(vertex_distance, min_in_weight);
BGL_FORALL_VERTICES_T(v, g, Graph) {
if (in_edges(v, g).first != in_edges(v, g).second) {
std::cerr << "weights(" << g.distribution().global(get(local, v))
<< ") = ";
BGL_FORALL_INEDGES_T(v, e, g, Graph) {
std::cerr << get(weight, e) << ' ';
}
std::cerr << std::endl;
put(min_in_weight, v,
*std::min_element
(make_property_map_iterator(weight, in_edges(v, g).first),
make_property_map_iterator(weight, in_edges(v, g).second),
compare));
} else {
put(min_in_weight, v, 0);
}
std::cerr << "miw(" << g.distribution().global(get(local, v)) << ") = "
<< get(min_in_weight, v) << std::endl;
}
#else
initialize_min_in_weights(g, min_in_weight, weight, inf, compare,
directed_tag(), incidence_graph_tag());
#endif
}
template<typename Graph, typename MinInWeightMap, typename WeightMap,
typename Inf, typename Compare>
inline void
initialize_min_in_weights(const Graph&, MinInWeightMap, WeightMap, Inf,
Compare, undirected_tag, bidirectional_graph_tag)
{
// In weights are the same as out weights, so do nothing
}
/************************************************************************/
/************************************************************************
* Initialize the property map that contains the minimum outgoing edge *
( run in 2.332 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )