Boost-Geometry-Utils
view release on metacpan or search on metacpan
src/boost/graph/distributed/eager_dijkstra_shortest_paths.hpp view on Meta::CPAN
#ifdef MUTABLE_QUEUE
typedef mutable_queue<vertex_descriptor, std::vector<vertex_descriptor>,
queue_compare_type, VertexIndexMap> queue_type;
#else
typedef relaxed_heap<vertex_descriptor, queue_compare_type,
VertexIndexMap> queue_type;
#endif // MUTABLE_QUEUE
typedef typename process_group_type::process_id_type process_id_type;
public:
typedef vertex_descriptor value_type;
lookahead_dijkstra_queue(const Graph& g,
const Combine& combine,
const Compare& compare,
const VertexIndexMap& id,
const DistanceMap& distance_map,
const PredecessorMap& predecessor_map,
distance_type lookahead)
: inherited(boost::graph::parallel::process_group(g), get(vertex_owner, g)),
queue(num_vertices(g), queue_compare_type(distance_map, compare), id),
distance_map(distance_map),
predecessor_map(predecessor_map),
min_distance(0),
lookahead(lookahead)
#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()
{
queue.pop();
#ifdef PBGL_ACCOUNTING
++local_deletions;
#endif
}
value_type& top() { return queue.top(); }
const value_type& top() const { return queue.top(); }
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;
}
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
{
return (!queue.empty()
&& get(distance_map, queue.top()) <= min_distance + lookahead);
}
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_distance =
queue.empty()? (std::numeric_limits<distance_type>::max)()
: get(distance_map, queue.top());
all_reduce(this->process_group, &local_distance, &local_distance + 1,
&min_distance, minimum<distance_type>());
#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)
eager_dijkstra_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)();
}
public:
void
receive_update(process_id_type source, vertex_descriptor vertex,
distance_type distance)
{
// Update the queue if the received distance is better than
// the distance we know locally
if (distance <= get(distance_map, vertex)) {
// Update the local distance map
put(distance_map, vertex, distance);
bool is_in_queue = queue.contains(vertex);
if (!is_in_queue)
queue.push(vertex);
else
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:
queue_type queue;
DistanceMap distance_map;
PredecessorMap predecessor_map;
distance_type min_distance;
( run in 0.875 second using v1.01-cache-2.11-cpan-39bf76dae61 )