dijkstra_example.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  6. <meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
  7. <title>Parallel Shortest Paths</title>
  8. <link rel="stylesheet" href="../../../../rst.css" type="text/css" />
  9. </head>
  10. <body>
  11. <div class="document" id="parallel-shortest-paths">
  12. <h1 class="title">Parallel Shortest Paths</h1>
  13. <!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
  14. Use, modification and distribution is subject to the Boost Software
  15. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  16. http://www.boost.org/LICENSE_1_0.txt) -->
  17. <p>To illustrate the use of the Parallel Boost Graph Library, we
  18. illustrate the use of both the sequential and parallel BGL to find
  19. the shortest paths from vertex A to every other vertex in the
  20. following simple graph:</p>
  21. <img alt="../dijkstra_seq_graph.png" src="../dijkstra_seq_graph.png" />
  22. <p>With the sequential <a class="reference external" href="http://www.boost.org/libs/graph/doc">BGL</a>, the program to calculate shortest paths has
  23. three stages. Readers familiar with the BGL may wish to skip ahead to
  24. the section <a class="reference internal" href="#distributing-the-graph">Distributing the graph</a>.</p>
  25. <blockquote>
  26. <ul class="simple">
  27. <li><a class="reference internal" href="#define-the-graph-type">Define the graph type</a></li>
  28. <li><a class="reference internal" href="#construct-the-graph">Construct the graph</a></li>
  29. <li><a class="reference internal" href="#invoke-dijkstra-s-algorithm">Invoke Dijkstra's algorithm</a></li>
  30. </ul>
  31. </blockquote>
  32. <div class="section" id="define-the-graph-type">
  33. <h1>Define the graph type</h1>
  34. <p>For this problem we use an adjacency list representation of the graph,
  35. using the BGL <tt class="docutils literal"><span class="pre">adjacency_list``_</span> <span class="pre">class</span> <span class="pre">template.</span> <span class="pre">It</span> <span class="pre">will</span> <span class="pre">be</span> <span class="pre">a</span> <span class="pre">directed</span>
  36. <span class="pre">graph</span> <span class="pre">(``directedS</span></tt> parameter ) whose vertices are stored in an
  37. <tt class="docutils literal"><span class="pre">std::vector</span></tt> (<tt class="docutils literal"><span class="pre">vecS</span></tt> parameter) where the outgoing edges of each
  38. vertex are stored in an <tt class="docutils literal"><span class="pre">std::list</span></tt> (<tt class="docutils literal"><span class="pre">listS</span></tt> parameter). To each
  39. of the edges we attach an integral weight.</p>
  40. <pre class="literal-block">
  41. typedef adjacency_list&lt;listS, vecS, directedS,
  42. no_property, // Vertex properties
  43. property&lt;edge_weight_t, int&gt; // Edge properties
  44. &gt; graph_t;
  45. typedef graph_traits &lt; graph_t &gt;::vertex_descriptor vertex_descriptor;
  46. typedef graph_traits &lt; graph_t &gt;::edge_descriptor edge_descriptor;
  47. </pre>
  48. </div>
  49. <div class="section" id="construct-the-graph">
  50. <h1>Construct the graph</h1>
  51. <p>To build the graph, we declare an enumeration containing the node
  52. names (for our own use) and create two arrays: the first,
  53. <tt class="docutils literal"><span class="pre">edge_array</span></tt>, contains the source and target of each edge, whereas
  54. the second, <tt class="docutils literal"><span class="pre">weights</span></tt>, contains the integral weight of each
  55. edge. We pass the contents of the arrays via pointers (used here as
  56. iterators) to the graph constructor to build our graph:</p>
  57. <pre class="literal-block">
  58. typedef std::pair&lt;int, int&gt; Edge;
  59. const int num_nodes = 5;
  60. enum nodes { A, B, C, D, E };
  61. char name[] = &quot;ABCDE&quot;;
  62. Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E),
  63. Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B)
  64. };
  65. int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 };
  66. int num_arcs = sizeof(edge_array) / sizeof(Edge);
  67. graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
  68. </pre>
  69. </div>
  70. <div class="section" id="invoke-dijkstra-s-algorithm">
  71. <h1>Invoke Dijkstra's algorithm</h1>
  72. <p>To invoke Dijkstra's algorithm, we need to first decide how we want
  73. to receive the results of the algorithm, namely the distance to each
  74. vertex and the predecessor of each vertex (allowing reconstruction of
  75. the shortest paths themselves). In our case, we will create two
  76. vectors, <tt class="docutils literal"><span class="pre">p</span></tt> for predecessors and <tt class="docutils literal"><span class="pre">d</span></tt> for distances.</p>
  77. <p>Next, we determine our starting vertex <tt class="docutils literal"><span class="pre">s</span></tt> using the <tt class="docutils literal"><span class="pre">vertex</span></tt>
  78. operation on the <tt class="docutils literal"><span class="pre">adjacency_list``_</span> <span class="pre">and</span> <span class="pre">call</span>
  79. <span class="pre">``dijkstra_shortest_paths``_</span> <span class="pre">with</span> <span class="pre">the</span> <span class="pre">graph</span> <span class="pre">``g</span></tt>, starting vertex
  80. <tt class="docutils literal"><span class="pre">s</span></tt>, and two <tt class="docutils literal"><span class="pre">property</span> <span class="pre">maps``_</span> <span class="pre">that</span> <span class="pre">instruct</span> <span class="pre">the</span> <span class="pre">algorithm</span> <span class="pre">to</span>
  81. <span class="pre">store</span> <span class="pre">predecessors</span> <span class="pre">in</span> <span class="pre">the</span> <span class="pre">``p</span></tt> vector and distances in the <tt class="docutils literal"><span class="pre">d</span></tt>
  82. vector. The algorithm automatically uses the edge weights stored
  83. within the graph, although this capability can be overridden.</p>
  84. <pre class="literal-block">
  85. // Keeps track of the predecessor of each vertex
  86. std::vector&lt;vertex_descriptor&gt; p(num_vertices(g));
  87. // Keeps track of the distance to each vertex
  88. std::vector&lt;int&gt; d(num_vertices(g));
  89. vertex_descriptor s = vertex(A, g);
  90. dijkstra_shortest_paths
  91. (g, s,
  92. predecessor_map(
  93. make_iterator_property_map(p.begin(), get(vertex_index, g))).
  94. distance_map(
  95. make_iterator_property_map(d.begin(), get(vertex_index, g)))
  96. );
  97. </pre>
  98. </div>
  99. <div class="section" id="distributing-the-graph">
  100. <h1>Distributing the graph</h1>
  101. <p>The prior computation is entirely sequential, with the graph stored
  102. within a single address space. To distribute the graph across several
  103. processors without a shared address space, we need to represent the
  104. processors and communication among them and alter the graph type.</p>
  105. <p>Processors and their interactions are abstracted via a <em>process
  106. group</em>. In our case, we will use <a class="reference external" href="http://www-unix.mcs.anl.gov/mpi/">MPI</a> for communication with
  107. inter-processor messages sent immediately:</p>
  108. <pre class="literal-block">
  109. typedef mpi::process_group&lt;mpi::immediateS&gt; process_group_type;
  110. </pre>
  111. <p>Next, we instruct the <tt class="docutils literal"><span class="pre">adjacency_list</span></tt> template
  112. to distribute the vertices of the graph across our process group,
  113. storing the local vertices in an <tt class="docutils literal"><span class="pre">std::vector</span></tt>:</p>
  114. <pre class="literal-block">
  115. typedef adjacency_list&lt;listS,
  116. distributedS&lt;process_group_type, vecS&gt;,
  117. directedS,
  118. no_property, // Vertex properties
  119. property&lt;edge_weight_t, int&gt; // Edge properties
  120. &gt; graph_t;
  121. typedef graph_traits &lt; graph_t &gt;::vertex_descriptor vertex_descriptor;
  122. typedef graph_traits &lt; graph_t &gt;::edge_descriptor edge_descriptor;
  123. </pre>
  124. <p>Note that the only difference from the sequential BGL is the use of
  125. the <tt class="docutils literal"><span class="pre">distributedS</span></tt> selector, which identifies a distributed
  126. graph. The vertices of the graph will be distributed among the
  127. various processors, and the processor that owns a vertex also stores
  128. the edges outgoing from that vertex and any properties associated
  129. with that vertex or its edges. With three processors and the default
  130. block distribution, the graph would be distributed in this manner:</p>
  131. <img alt="../dijkstra_dist3_graph.png" src="../dijkstra_dist3_graph.png" />
  132. <p>Processor 0 (red) owns vertices A and B, including all edges outoing
  133. from those vertices, processor 1 (green) owns vertices C and D (and
  134. their edges), and processor 2 (blue) owns vertex E. Constructing this
  135. graph uses the same syntax is the sequential graph, as in the section
  136. <a class="reference internal" href="#construct-the-graph">Construct the graph</a>.</p>
  137. <p>The call to <tt class="docutils literal"><span class="pre">dijkstra_shortest_paths</span></tt> is syntactically equivalent to
  138. the sequential call, but the mechanisms used are very different. The
  139. property maps passed to <tt class="docutils literal"><span class="pre">dijkstra_shortest_paths</span></tt> are actually
  140. <em>distributed</em> property maps, which store properties for local edges
  141. or vertices and perform implicit communication to access properties
  142. of remote edges or vertices when needed. The formulation of Dijkstra's
  143. algorithm is also slightly different, because each processor can
  144. only attempt to relax edges outgoing from local vertices: as shorter
  145. paths to a vertex are discovered, messages to the processor owning
  146. that vertex indicate that the vertex may require reprocessing.</p>
  147. <hr class="docutils" />
  148. <p>Return to the <a class="reference external" href="index.html">Parallel BGL home page</a></p>
  149. </div>
  150. </div>
  151. <div class="footer">
  152. <hr class="footer" />
  153. Generated on: 2009-05-31 00:22 UTC.
  154. Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
  155. </div>
  156. </body>
  157. </html>