PageRenderTime 53ms CodeModel.GetById 8ms app.highlight 39ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/graph/distributed/crauser_et_al_shortest_paths.hpp

http://hadesmem.googlecode.com/
C++ Header | 665 lines | 499 code | 91 blank | 75 comment | 27 complexity | 99c93bec9a1f11bfc311f4b898c6be3d MD5 | raw file
  1// Copyright (C) 2004-2006 The Trustees of Indiana University.
  2
  3// Use, modification and distribution is subject to the Boost Software
  4// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5// http://www.boost.org/LICENSE_1_0.txt)
  6
  7//  Authors: Douglas Gregor
  8//           Andrew Lumsdaine
  9
 10/**************************************************************************
 11 * This source file implements the variation on Dijkstra's algorithm      *
 12 * presented by Crauser et al. in:                                        *
 13 *                                                                        *
 14 *   Andreas Crauser, Kurt Mehlhorn, Ulrich Meyer, and Peter              *
 15 *   Sanders. A Parallelization of Dijkstra's Shortest Path               *
 16 *   Algorithm. In Lubos Brim, Jozef Gruska, and Jiri Zlatuska,          *
 17 *   editors, Mathematical Foundations of Computer Science (MFCS),        *
 18 *   volume 1450 of Lecture Notes in Computer Science, pages              *
 19 *   722--731, 1998. Springer.                                            *
 20 *                                                                        *
 21 * This implementation is, however, restricted to the distributed-memory  *
 22 * case, where the work is distributed by virtue of the vertices being    *
 23 * distributed. In a shared-memory (single address space) context, we     *
 24 * would want to add an explicit balancing step.                          *
 25 **************************************************************************/
 26#ifndef BOOST_GRAPH_CRAUSER_ET_AL_SHORTEST_PATHS_HPP
 27#define BOOST_GRAPH_CRAUSER_ET_AL_SHORTEST_PATHS_HPP
 28
 29#ifndef BOOST_GRAPH_USE_MPI
 30#error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
 31#endif
 32
 33#include <boost/assert.hpp>
 34#include <boost/graph/distributed/detail/dijkstra_shortest_paths.hpp>
 35#include <boost/graph/parallel/algorithm.hpp>
 36#include <functional>
 37#include <boost/graph/iteration_macros.hpp>
 38#include <boost/property_map/property_map_iterator.hpp>
 39#include <boost/type_traits/is_same.hpp>
 40#include <algorithm>
 41#include <boost/property_map/parallel/caching_property_map.hpp>
 42#include <boost/pending/indirect_cmp.hpp>
 43#include <boost/graph/distributed/detail/remote_update_set.hpp>
 44#include <vector>
 45#include <boost/graph/breadth_first_search.hpp>
 46#include <boost/graph/dijkstra_shortest_paths.hpp>
 47#include <boost/graph/parallel/container_traits.hpp>
 48
 49#ifdef PBGL_ACCOUNTING
 50#  include <boost/graph/accounting.hpp>
 51#  include <numeric>
 52#endif // PBGL_ACCOUNTING
 53
 54#ifdef MUTABLE_QUEUE
 55#    include <boost/pending/mutable_queue.hpp>
 56#endif
 57
 58namespace boost { namespace graph { namespace distributed {
 59
 60#ifdef PBGL_ACCOUNTING
 61struct crauser_et_al_shortest_paths_stats_t
 62{
 63  /* Total wall-clock time used by the algorithm.*/
 64  accounting::time_type execution_time;
 65
 66  /* The number of vertices deleted in each superstep. */
 67  std::vector<std::size_t> deleted_vertices;
 68
 69  template<typename OutputStream>
 70  void print(OutputStream& out)
 71  {
 72    double avg_deletions = std::accumulate(deleted_vertices.begin(),
 73                                           deleted_vertices.end(),
 74                                           0.0);
 75    avg_deletions /= deleted_vertices.size();
 76
 77    out << "Problem = \"Single-Source Shortest Paths\"\n"
 78        << "Algorithm = \"Crauser et al\"\n"
 79        << "Function = crauser_et_al_shortest_paths\n"
 80        << "Wall clock time = " << accounting::print_time(execution_time)
 81        << "\nSupersteps = " << deleted_vertices.size() << "\n"
 82        << "Avg. deletions per superstep = " << avg_deletions << "\n";
 83  }
 84};
 85
 86static crauser_et_al_shortest_paths_stats_t crauser_et_al_shortest_paths_stats;
 87#endif
 88
 89namespace detail {
 90
 91  /************************************************************************
 92   * Function objects that perform distance comparisons modified by the   *
 93   * minimum or maximum edge weights.                                     *
 94   ************************************************************************/
 95  template<typename Vertex, typename DistanceMap, typename MinInWeightMap,
 96           typename Combine, typename Compare>
 97  struct min_in_distance_compare
 98    : std::binary_function<Vertex, Vertex, bool>
 99  {
100    min_in_distance_compare(DistanceMap d, MinInWeightMap m,
101                            Combine combine, Compare compare)
102      : distance_map(d), min_in_weight(m), combine(combine),
103        compare(compare)
104    {
105    }
106
107    bool operator()(const Vertex& x, const Vertex& y) const
108    {
109      return compare(combine(get(distance_map, x), -get(min_in_weight, x)),
110                     combine(get(distance_map, y), -get(min_in_weight, y)));
111    }
112
113  private:
114    DistanceMap distance_map;
115    MinInWeightMap min_in_weight;
116    Combine combine;
117    Compare compare;
118  };
119
120  template<typename Vertex, typename DistanceMap, typename MinOutWeightMap,
121           typename Combine, typename Compare>
122  struct min_out_distance_compare
123    : std::binary_function<Vertex, Vertex, bool>
124  {
125    min_out_distance_compare(DistanceMap d, MinOutWeightMap m,
126                             Combine combine, Compare compare)
127      : distance_map(d), min_out_weight(m), combine(combine),
128        compare(compare)
129    {
130    }
131
132    bool operator()(const Vertex& x, const Vertex& y) const
133    {
134      return compare(combine(get(distance_map, x), get(min_out_weight, x)),
135                     combine(get(distance_map, y), get(min_out_weight, y)));
136    }
137
138  private:
139    DistanceMap distance_map;
140    MinOutWeightMap min_out_weight;
141    Combine combine;
142    Compare compare;
143  };
144  /************************************************************************/
145
146  /************************************************************************
147   * Dijkstra queue that implements Crauser et al.'s criteria. This queue *
148   * actually stores three separate priority queues, to help expose all   *
149   * vertices that can be processed in a single phase.                    *
150   ************************************************************************/
151  template<typename Graph, typename Combine,
152           typename Compare, typename VertexIndexMap, typename DistanceMap,
153           typename PredecessorMap, typename MinOutWeightMap,
154           typename MinInWeightMap>
155  class crauser_et_al_dijkstra_queue
156    : public graph::detail::remote_update_set<
157               crauser_et_al_dijkstra_queue<
158                 Graph, Combine, Compare, VertexIndexMap, DistanceMap, 
159                 PredecessorMap, MinOutWeightMap, MinInWeightMap>,
160               typename boost::graph::parallel::process_group_type<Graph>::type,
161               typename dijkstra_msg_value<DistanceMap, PredecessorMap>::type,
162               typename property_map<Graph, vertex_owner_t>::const_type>
163  {
164    typedef typename graph_traits<Graph>::vertex_descriptor
165      vertex_descriptor;
166    typedef crauser_et_al_dijkstra_queue self_type;
167    typedef dijkstra_msg_value<DistanceMap, PredecessorMap> msg_value_creator;
168    typedef typename msg_value_creator::type msg_value_type;
169    typedef typename graph_traits<Graph>::vertices_size_type
170      vertices_size_type;
171    typedef typename property_map<Graph, vertex_owner_t>::const_type
172      OwnerPropertyMap;
173    typedef typename boost::graph::parallel::process_group_type<Graph>::type
174      process_group_type;
175    typedef graph::detail::remote_update_set<self_type, process_group_type,
176                                             msg_value_type, OwnerPropertyMap>
177      inherited;
178
179    // Priority queue for tentative distances
180    typedef indirect_cmp<DistanceMap, Compare> dist_queue_compare_type;
181
182    typedef typename property_traits<DistanceMap>::value_type distance_type;
183
184#ifdef MUTABLE_QUEUE
185    typedef mutable_queue<vertex_descriptor, std::vector<vertex_descriptor>, 
186                          dist_queue_compare_type, VertexIndexMap> dist_queue_type;
187
188#else
189    typedef relaxed_heap<vertex_descriptor, dist_queue_compare_type,
190                         VertexIndexMap> dist_queue_type;
191#endif // MUTABLE_QUEUE
192
193    // Priority queue for OUT criteria
194    typedef min_out_distance_compare<vertex_descriptor, DistanceMap,
195                                     MinOutWeightMap, Combine, Compare>
196      out_queue_compare_type;
197
198#ifdef MUTABLE_QUEUE
199    typedef mutable_queue<vertex_descriptor, std::vector<vertex_descriptor>, 
200                          out_queue_compare_type, VertexIndexMap> out_queue_type;
201
202#else
203    typedef relaxed_heap<vertex_descriptor, out_queue_compare_type,
204                         VertexIndexMap> out_queue_type;
205#endif // MUTABLE_QUEUE
206
207    // Priority queue for IN criteria
208    typedef min_in_distance_compare<vertex_descriptor, DistanceMap,
209                                    MinInWeightMap, Combine, Compare>
210      in_queue_compare_type;
211
212#ifdef MUTABLE_QUEUE
213    typedef mutable_queue<vertex_descriptor, std::vector<vertex_descriptor>, 
214                          in_queue_compare_type, VertexIndexMap> in_queue_type;
215
216#else
217    typedef relaxed_heap<vertex_descriptor, in_queue_compare_type,
218                         VertexIndexMap> in_queue_type;
219#endif // MUTABLE_QUEUE
220
221    typedef typename process_group_type::process_id_type process_id_type;
222
223  public:
224    typedef typename dist_queue_type::size_type  size_type;
225    typedef typename dist_queue_type::value_type value_type;
226
227    crauser_et_al_dijkstra_queue(const Graph& g,
228                                 const Combine& combine,
229                                 const Compare& compare,
230                                 const VertexIndexMap& id,
231                                 const DistanceMap& distance_map,
232                                 const PredecessorMap& predecessor_map,
233                                 const MinOutWeightMap& min_out_weight,
234                                 const MinInWeightMap& min_in_weight)
235      : inherited(boost::graph::parallel::process_group(g), get(vertex_owner, g)),
236        dist_queue(num_vertices(g),
237                   dist_queue_compare_type(distance_map, compare),
238                   id),
239        out_queue(num_vertices(g),
240                  out_queue_compare_type(distance_map, min_out_weight,
241                                         combine, compare),
242                  id),
243        in_queue(num_vertices(g),
244                 in_queue_compare_type(distance_map, min_in_weight,
245                                       combine, compare),
246                 id),
247        g(g),
248        distance_map(distance_map),
249        predecessor_map(predecessor_map),
250        min_out_weight(min_out_weight),
251        min_in_weight(min_in_weight),
252        min_distance(0),
253        min_out_distance(0)
254#ifdef PBGL_ACCOUNTING
255        , local_deletions(0)
256#endif
257    { }
258
259    void push(const value_type& x)
260    {
261      msg_value_type msg_value =
262        msg_value_creator::create(get(distance_map, x),
263                                  predecessor_value(get(predecessor_map, x)));
264      inherited::update(x, msg_value);
265    }
266
267    void update(const value_type& x) { push(x); }
268
269    void pop()
270    {
271      // Remove from distance queue
272      dist_queue.remove(top_vertex);
273
274      // Remove from OUT queue
275      out_queue.remove(top_vertex);
276
277      // Remove from IN queue
278      in_queue.remove(top_vertex);
279
280#ifdef PBGL_ACCOUNTING
281      ++local_deletions;
282#endif
283    }
284
285    vertex_descriptor& top() { return top_vertex; }
286    const vertex_descriptor& top() const { return top_vertex; }
287
288    bool empty()
289    {
290      inherited::collect();
291
292      // If there are no suitable messages, wait until we get something
293      while (!has_suitable_vertex()) {
294        if (do_synchronize()) return true;
295      }
296      // Return true only if nobody has any messages; false if we
297      // have suitable messages
298      return false;
299    }
300
301    bool do_synchronize()
302    {
303      using boost::parallel::all_reduce;
304      using boost::parallel::minimum;
305
306      inherited::synchronize();
307
308      // TBD: could use combine here, but then we need to stop using
309      // minimum<distance_type>() as the function object.
310      distance_type local_distances[2];
311      local_distances[0] =
312        dist_queue.empty()? (std::numeric_limits<distance_type>::max)()
313        : get(distance_map, dist_queue.top());
314
315      local_distances[1] =
316        out_queue.empty()? (std::numeric_limits<distance_type>::max)()
317        : (get(distance_map, out_queue.top())
318           + get(min_out_weight, out_queue.top()));
319
320      distance_type distances[2];
321      all_reduce(this->process_group, local_distances, local_distances + 2,
322                 distances, minimum<distance_type>());
323      min_distance = distances[0];
324      min_out_distance = distances[1];
325
326#ifdef PBGL_ACCOUNTING
327      std::size_t deletions = 0;
328      all_reduce(this->process_group, &local_deletions, &local_deletions + 1,
329                 &deletions, std::plus<std::size_t>());
330      if (process_id(this->process_group) == 0) {
331        crauser_et_al_shortest_paths_stats.deleted_vertices.push_back(deletions);
332      }
333      local_deletions = 0;
334      BOOST_ASSERT(deletions > 0);
335#endif
336
337      return min_distance == (std::numeric_limits<distance_type>::max)();
338    }
339
340  private:
341    vertex_descriptor predecessor_value(vertex_descriptor v) const
342    { return v; }
343
344    vertex_descriptor
345    predecessor_value(property_traits<dummy_property_map>::reference) const
346    { return graph_traits<Graph>::null_vertex(); }
347
348    bool has_suitable_vertex() const
349    {
350      if (!dist_queue.empty()) {
351        top_vertex = dist_queue.top();
352        if (get(distance_map, dist_queue.top()) <= min_out_distance)
353          return true;
354      }
355
356      if (!in_queue.empty()) {
357        top_vertex = in_queue.top();
358        return (get(distance_map, top_vertex)
359                - get(min_in_weight, top_vertex)) <= min_distance;
360      }
361      return false;
362    }
363
364  public:
365    void
366    receive_update(process_id_type source, vertex_descriptor vertex,
367                   distance_type distance)
368    {
369      // Update the queue if the received distance is better than
370      // the distance we know locally
371      if (distance < get(distance_map, vertex)
372          || (distance == get(distance_map, vertex)
373              && source == process_id(this->process_group))) {
374        // Update the local distance map
375        put(distance_map, vertex, distance);
376
377        bool is_in_queue = dist_queue.contains(vertex);
378
379        if (!is_in_queue) {
380          dist_queue.push(vertex);
381          out_queue.push(vertex);
382          in_queue.push(vertex);
383        }
384        else {
385          dist_queue.update(vertex);
386          out_queue.update(vertex);
387          in_queue.update(vertex);
388        }
389      }
390    }
391
392    void
393    receive_update(process_id_type source, vertex_descriptor vertex,
394                   std::pair<distance_type, vertex_descriptor> p)
395    {
396      if (p.first <= get(distance_map, vertex)) {
397        put(predecessor_map, vertex, p.second);
398        receive_update(source, vertex, p.first);
399      }
400    }
401
402  private:
403    dist_queue_type           dist_queue;
404    out_queue_type            out_queue;
405    in_queue_type             in_queue;
406    mutable value_type        top_vertex;
407    const Graph&              g;
408    DistanceMap               distance_map;
409    PredecessorMap            predecessor_map;
410    MinOutWeightMap           min_out_weight;
411    MinInWeightMap            min_in_weight;
412    distance_type             min_distance;
413    distance_type             min_out_distance;
414#ifdef PBGL_ACCOUNTING
415    std::size_t               local_deletions;
416#endif
417  };
418  /************************************************************************/
419
420  /************************************************************************
421   * Initialize the property map that contains the minimum incoming edge  *
422   * weight for each vertex. There are separate implementations for       *
423   * directed, bidirectional, and undirected graph.                       *
424   ************************************************************************/
425  template<typename Graph, typename MinInWeightMap, typename WeightMap,
426           typename Inf, typename Compare>
427  void
428  initialize_min_in_weights(const Graph& g, MinInWeightMap min_in_weight,
429                            WeightMap weight, Inf inf, Compare compare,
430                            directed_tag, incidence_graph_tag)
431  {
432    // Send minimum weights off to the owners
433    set_property_map_role(vertex_distance, min_in_weight);
434    BGL_FORALL_VERTICES_T(v, g, Graph) {
435      BGL_FORALL_OUTEDGES_T(v, e, g, Graph) {
436        if (get(weight, e) < get(min_in_weight, target(e, g)))
437          put(min_in_weight, target(e, g), get(weight, e));
438      }
439    }
440
441    using boost::graph::parallel::process_group;
442    synchronize(process_group(g));
443
444    // Replace any infinities with zeros
445    BGL_FORALL_VERTICES_T(v, g, Graph) {
446      if (get(min_in_weight, v) == inf) put(min_in_weight, v, 0);
447    }
448  }
449
450  template<typename Graph, typename MinInWeightMap, typename WeightMap,
451           typename Inf, typename Compare>
452  void
453  initialize_min_in_weights(const Graph& g, MinInWeightMap min_in_weight,
454                            WeightMap weight, Inf inf, Compare compare,
455                            directed_tag, bidirectional_graph_tag)
456  {
457#if 0
458    typename property_map<Graph, vertex_local_t>::const_type
459      local = get(vertex_local, g);
460
461    // This code assumes that the properties of the in-edges are
462    // available locally. This is not necessarily the case, so don't
463    // do this yet.
464    set_property_map_role(vertex_distance, min_in_weight);
465    BGL_FORALL_VERTICES_T(v, g, Graph) {
466      if (in_edges(v, g).first != in_edges(v, g).second) {
467        std::cerr << "weights(" << g.distribution().global(get(local, v))
468                  << ") = ";
469        BGL_FORALL_INEDGES_T(v, e, g, Graph) {
470          std::cerr << get(weight, e) << ' ';
471        }
472        std::cerr << std::endl;
473        put(min_in_weight, v,
474            *std::min_element
475            (make_property_map_iterator(weight, in_edges(v, g).first),
476             make_property_map_iterator(weight, in_edges(v, g).second),
477             compare));
478      } else {
479        put(min_in_weight, v, 0);
480      }
481      std::cerr << "miw(" << g.distribution().global(get(local, v)) << ") = "
482                << get(min_in_weight, v) << std::endl;
483    }
484#else
485    initialize_min_in_weights(g, min_in_weight, weight, inf, compare,
486                              directed_tag(), incidence_graph_tag());
487#endif
488  }
489
490  template<typename Graph, typename MinInWeightMap, typename WeightMap,
491           typename Inf, typename Compare>
492  inline void
493  initialize_min_in_weights(const Graph&, MinInWeightMap, WeightMap, Inf,
494                            Compare, undirected_tag, bidirectional_graph_tag)
495  {
496    // In weights are the same as out weights, so do nothing
497  }
498  /************************************************************************/
499
500
501  /************************************************************************
502   * Initialize the property map that contains the minimum outgoing edge  *
503   * weight for each vertex.                                              *
504   ************************************************************************/
505  template<typename Graph, typename MinOutWeightMap, typename WeightMap,
506           typename Compare>
507  void
508  initialize_min_out_weights(const Graph& g, MinOutWeightMap min_out_weight,
509                             WeightMap weight, Compare compare)
510  {
511    typedef typename property_traits<WeightMap>::value_type weight_type;
512
513    BGL_FORALL_VERTICES_T(v, g, Graph) {
514      if (out_edges(v, g).first != out_edges(v, g).second) {
515        put(min_out_weight, v,
516            *std::min_element
517            (make_property_map_iterator(weight, out_edges(v, g).first),
518             make_property_map_iterator(weight, out_edges(v, g).second),
519             compare));
520        if (get(min_out_weight, v) < weight_type(0))
521            boost::throw_exception(negative_edge());
522      }
523    }
524  }
525
526  /************************************************************************/
527
528} // end namespace detail
529
530template<typename DistributedGraph, typename DijkstraVisitor,
531         typename PredecessorMap, typename DistanceMap, typename WeightMap,
532         typename IndexMap, typename ColorMap, typename Compare,
533         typename Combine, typename DistInf, typename DistZero>
534void
535crauser_et_al_shortest_paths
536  (const DistributedGraph& g,
537   typename graph_traits<DistributedGraph>::vertex_descriptor s,
538   PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
539   IndexMap index_map, ColorMap color_map,
540   Compare compare, Combine combine, DistInf inf, DistZero zero,
541   DijkstraVisitor vis)
542{
543  typedef typename boost::graph::parallel::process_group_type<DistributedGraph>::type
544    process_group_type;
545  typedef typename process_group_type::process_id_type process_id_type;
546  typedef typename graph_traits<DistributedGraph>::vertex_descriptor
547    Vertex;
548  typedef typename graph_traits<DistributedGraph>::vertices_size_type
549    vertices_size_type;
550
551#ifdef PBGL_ACCOUNTING
552  crauser_et_al_shortest_paths_stats.deleted_vertices.clear();
553  crauser_et_al_shortest_paths_stats.execution_time = accounting::get_time();
554#endif
555
556  // Property map that stores the lowest edge weight outgoing from
557  // each vertex. If a vertex has no out-edges, the stored weight
558  // is zero.
559  typedef typename property_traits<WeightMap>::value_type weight_type;
560  typedef iterator_property_map<weight_type*, IndexMap> MinOutWeightMap;
561  std::vector<weight_type> min_out_weights_vec(num_vertices(g), inf);
562  MinOutWeightMap min_out_weight(&min_out_weights_vec.front(), index_map);
563  detail::initialize_min_out_weights(g, min_out_weight, weight, compare);
564
565  // Property map that stores the lowest edge weight incoming to
566  // each vertex. For undirected graphs, this will just be a
567  // shallow copy of the version for outgoing edges.
568  typedef typename graph_traits<DistributedGraph>::directed_category
569    directed_category;
570  const bool is_undirected =
571    is_same<directed_category, undirected_tag>::value;
572  typedef MinOutWeightMap MinInWeightMap;
573  std::vector<weight_type>
574    min_in_weights_vec(is_undirected? 1 : num_vertices(g), inf);
575  MinInWeightMap min_in_weight(&min_in_weights_vec.front(), index_map);
576  typedef typename graph_traits<DistributedGraph>::traversal_category
577    category;
578  detail::initialize_min_in_weights(g, min_in_weight, weight, inf, compare,
579                                    directed_category(), category());
580
581  // Initialize local portion of property maps
582  typename graph_traits<DistributedGraph>::vertex_iterator ui, ui_end;
583  for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
584    put(distance, *ui, inf);
585    put(predecessor, *ui, *ui);
586  }
587  put(distance, s, zero);
588
589  // Dijkstra Queue
590  typedef detail::crauser_et_al_dijkstra_queue
591            <DistributedGraph, Combine, Compare, IndexMap, DistanceMap, 
592             PredecessorMap, MinOutWeightMap, MinInWeightMap>
593    Queue;
594
595  Queue Q(g, combine, compare, index_map, distance, predecessor,
596          min_out_weight, is_undirected? min_out_weight : min_in_weight);
597
598  // Parallel Dijkstra visitor
599  ::boost::detail::dijkstra_bfs_visitor<
600      DijkstraVisitor, Queue, WeightMap,
601      boost::parallel::caching_property_map<PredecessorMap>,
602      boost::parallel::caching_property_map<DistanceMap>, Combine, Compare
603    > bfs_vis(vis, Q, weight,
604              boost::parallel::make_caching_property_map(predecessor),
605              boost::parallel::make_caching_property_map(distance),
606              combine, compare, zero);
607
608  set_property_map_role(vertex_color, color_map);
609  set_property_map_role(vertex_distance, distance);
610
611  breadth_first_search(g, s, Q, bfs_vis, color_map);
612
613#ifdef PBGL_ACCOUNTING
614  crauser_et_al_shortest_paths_stats.execution_time =
615    accounting::get_time() - crauser_et_al_shortest_paths_stats.execution_time;
616#endif
617}
618
619template<typename DistributedGraph, typename PredecessorMap,
620         typename DistanceMap, typename WeightMap>
621void
622crauser_et_al_shortest_paths
623  (const DistributedGraph& g,
624   typename graph_traits<DistributedGraph>::vertex_descriptor s,
625   PredecessorMap predecessor, DistanceMap distance, WeightMap weight)
626{
627  typedef typename property_traits<DistanceMap>::value_type distance_type;
628
629  std::vector<default_color_type> colors(num_vertices(g), white_color);
630
631  crauser_et_al_shortest_paths(g, s, predecessor, distance, weight,
632                               get(vertex_index, g),
633                               make_iterator_property_map(&colors[0],
634                                                          get(vertex_index, g)),
635                               std::less<distance_type>(),
636                               closed_plus<distance_type>(),
637                               (std::numeric_limits<distance_type>::max)(),
638                               distance_type(),
639                               dijkstra_visitor<>());
640}
641
642template<typename DistributedGraph, typename PredecessorMap,
643         typename DistanceMap>
644void
645crauser_et_al_shortest_paths
646  (const DistributedGraph& g,
647   typename graph_traits<DistributedGraph>::vertex_descriptor s,
648   PredecessorMap predecessor, DistanceMap distance)
649{
650  crauser_et_al_shortest_paths(g, s, predecessor, distance,
651                               get(edge_weight, g));
652}
653
654} // end namespace distributed
655
656#ifdef PBGL_ACCOUNTING
657using distributed::crauser_et_al_shortest_paths_stats;
658#endif
659
660using distributed::crauser_et_al_shortest_paths;
661
662
663} } // end namespace boost::graph
664
665#endif // BOOST_GRAPH_CRAUSER_ET_AL_SHORTEST_PATHS_HPP