quick_tour.html 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. <html>
  2. <!--
  3. Copyright (c) Jeremy Siek 2000
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. -->
  8. <head>
  9. <title>Quick Tour of Boost Graph Library</title>
  10. <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
  11. <meta name="ProgId" content="FrontPage.Editor.Document">
  12. </head>
  13. <body bgcolor="#ffffff" link="#0000ee" text="#000000" vlink="#551a8b" alink="#ff0000">
  14. <img src="../../../boost.png" alt="C++ Boost" width="277" height="86"><br clear>
  15. <h1>A Quick Tour of the Boost Graph Library</h1>
  16. <p>The domain of graph data structures and algorithms is in some respects more
  17. complicated than that of containers. The abstract iterator interface used by STL
  18. is not sufficiently rich to encompass the numerous ways that graph algorithms
  19. may traverse a graph. Instead, we formulate an abstract interface that serves
  20. the same purpose for graphs that iterators do for basic containers (though
  21. iterators still play a large role). <a href="#fig:analogy">Figure 1</a> depicts
  22. the analogy between the STL and the BGL.
  23. <p>&nbsp;</p>
  24. <div align="CENTER">
  25. <a name="fig:analogy"></a><a name="752"></a>
  26. <table>
  27. <caption valign="bottom"><strong>Figure 1:</strong> The analogy between the
  28. STL and the BGL.</caption>
  29. <tr>
  30. <td><img src="figs/analogy.gif" width="518" height="335"></td>
  31. </tr>
  32. </table>
  33. </div>
  34. <p>&nbsp;</p>
  35. The graph abstraction consists of a set of vertices (or nodes), and a set of
  36. edges (or arcs) that connect the vertices. <a href="#fig:quick-start">Figure 2</a>
  37. depicts a directed graph with five vertices (labeled 0 through 4) and 11 edges.
  38. The edges leaving a vertex are called the <i>out-edges</i> of the vertex. The
  39. edges <tt>{(0,1),(0,2),(0,3),(0,4)}</tt> are all out-edges of vertex 0. The
  40. edges entering a vertex are called the <i>in-edges</i> of the vertex. The edges <tt>{(0,4),(2,4),(3,4)}</tt>
  41. are all in-edges of vertex 4.
  42. <p>&nbsp;</p>
  43. <div align="CENTER">
  44. <a name="fig:quick-start"></a>
  45. <table>
  46. <caption valign="bottom"><strong>Figure 2:</strong> An example of a directed
  47. graph.</caption>
  48. <tr>
  49. <td><img src="figs/quick_start.gif" width="103" height="124"></td>
  50. </tr>
  51. </table>
  52. </div>
  53. <p>&nbsp;</p>
  54. <p>In the following sections we will use the BGL to construct this example graph
  55. and manipulate it in various ways. The complete source code for this example can
  56. be found in <a href="../example/quick_tour.cpp"><tt>examples/quick_tour.cpp</tt></a>.
  57. Each of the following sections discusses a &quot;slice&quot; of this example
  58. file. Excerpts from the output of the example program will also be listed.
  59. <p>&nbsp;
  60. <h2>Constructing a Graph</h2>
  61. <p>In this example we will use the BGL <a href="adjacency_list.html"><tt>adjacency_list</tt></a>
  62. class to demonstrate the main ideas in the BGL interface. The <tt>adjacency_list</tt>
  63. class provides a generalized version of the classic &quot;adjacency list&quot;
  64. data structure. The <tt>adjacency_list</tt> is a template class with six
  65. template parameters, though here we only fill in the first three parameters and
  66. use the defaults for the remaining three. The first two template arguments (<tt>vecS,
  67. vecS</tt>) determine the data structure used to represent the out-edges for each
  68. vertex in the graph and the data structure used to represent the graph's vertex
  69. set (see section <a href="using_adjacency_list.html#sec:choosing-graph-type">Choosing
  70. the <tt>Edgelist</tt> and <tt>VertexList</tt></a> for information about the
  71. tradeoffs of the different data structures). The third argument, <tt>bidirectionalS</tt>,
  72. selects a directed graph that provides access to both out and in-edges. The
  73. other options for the third argument are <tt>directedS</tt> which selects a
  74. directed graph with only out-edges, and <tt>undirectedS</tt> which selects an
  75. undirected graph.
  76. <p>Once we have the graph type selected, we can create the graph in <a href="#fig:quick-start">Figure
  77. 2</a> by declaring a graph object and filling in edges using the <a href="MutableGraph.html#sec:add-edge"><tt>add_edge()</tt></a>
  78. function of the <a href="MutableGraph.html">MutableGraph</a> interface (which <tt>adjacency_list</tt>
  79. implements). We use the array of pairs <tt>edge_array</tt> merely as a
  80. convenient way to explicitly create the edges for this example.
  81. <p>&nbsp;
  82. <pre>
  83. #include &lt;iostream&gt; // for std::cout
  84. #include &lt;utility&gt; // for std::pair
  85. #include &lt;algorithm&gt; // for std::for_each
  86. #include &lt;boost/graph/graph_traits.hpp&gt;
  87. #include &lt;boost/graph/adjacency_list.hpp&gt;
  88. #include &lt;boost/graph/dijkstra_shortest_paths.hpp&gt;
  89. using namespace boost;
  90. int main(int,char*[])
  91. {
  92. // create a typedef for the Graph type
  93. typedef adjacency_list&lt;vecS, vecS, bidirectionalS&gt; Graph;
  94. // Make convenient labels for the vertices
  95. enum { A, B, C, D, E, N };
  96. const int num_vertices = N;
  97. const char* name = "ABCDE";
  98. // writing out the edges in the graph
  99. typedef std::pair&lt;int, int&gt; Edge;
  100. Edge edge_array[] =
  101. { Edge(A,B), Edge(A,D), Edge(C,A), Edge(D,C),
  102. Edge(C,E), Edge(B,D), Edge(D,E) };
  103. const int num_edges = sizeof(edge_array)/sizeof(edge_array[0]);
  104. // declare a graph object
  105. Graph g(num_vertices);
  106. // add the edges to the graph object
  107. for (int i = 0; i &lt; num_edges; ++i)
  108. add_edge(edge_array[i].first, edge_array[i].second, g);
  109. ...
  110. return 0;
  111. }
  112. </pre>
  113. <p>Instead of calling the <tt>add_edge()</tt> function for each edge, we could
  114. use the <a href="adjacency_list.html#sec:iterator-constructor">edge iterator
  115. constructor</a> of the graph. This is typically more efficient than using <tt>add_edge()</tt>.
  116. Pointers to the <tt>edge_array</tt> can be viewed as iterators, so we can call
  117. the iterator constructor by passing pointers to the beginning and end of the
  118. array.
  119. <pre>
  120. Graph g(edge_array, edge_array + sizeof(edge_array) / sizeof(Edge), num_vertices);
  121. </pre>
  122. <p>Instead of creating a graph with a certain number of vertices to begin with,
  123. it is also possible to add and remove vertices with the <a href="MutableGraph.html#sec:add-vertex"><tt>add_vertex()</tt></a>
  124. and <a href="MutableGraph.html#sec:remove-vertex"><tt>remove_vertex()</tt></a>
  125. functions, also of the <a href="MutableGraph.html">MutableGraph</a> interface.
  126. <h2>Accessing the Vertex Set</h2>
  127. <p>Now that we have created a graph, we can use the graph interface to access
  128. the graph data in different ways. First we can access all of the vertices in the
  129. graph using the <a href="VertexListGraph.html#sec:vertices"><tt>vertices()</tt></a>
  130. function of the <a href="VertexListGraph.html">VertexListGraph</a> interface.
  131. This function returns a <tt>std::pair</tt> of <i>vertex iterators</i> (the <tt>first</tt>
  132. iterator points to the &quot;beginning&quot; of the vertices and the <tt>second</tt>
  133. iterator points &quot;past the end&quot;). Dereferencing a vertex iterator gives
  134. a vertex object. The type of the vertex iterator is given by the <a href="graph_traits.html"><tt>graph_traits</tt></a>
  135. class. Note that different graph classes can have different associated vertex
  136. iterator types, which is why we need the <tt>graph_traits</tt> class. Given some
  137. graph type, the <tt>graph_traits</tt> class will provide access to the <tt>vertex_iterator</tt>
  138. type.
  139. <p>The following example prints out the index for each of the vertices in the
  140. graph. All vertex and edge properties, including index, are accessed via
  141. property map objects. The <a href="property_map.html"><tt>property_map</tt></a>
  142. class is used to obtain the property map type for a specific property (specified
  143. by <tt>vertex_index_t</tt>, one of the BGL predefined properties) and function
  144. call <tt>get(vertex_index, g)</tt> returns the actual property map object.
  145. <p>&nbsp;
  146. <pre>
  147. // ...
  148. int main(int,char*[])
  149. {
  150. // ...
  151. typedef graph_traits&lt;Graph&gt;::vertex_descriptor Vertex;
  152. // get the property map for vertex indices
  153. typedef property_map&lt;Graph, vertex_index_t&gt;::type IndexMap;
  154. IndexMap index = get(vertex_index, g);
  155. std::cout &lt;&lt; &quot;vertices(g) = &quot;;
  156. typedef graph_traits&lt;Graph&gt;::vertex_iterator vertex_iter;
  157. std::pair&lt;vertex_iter, vertex_iter&gt; vp;
  158. for (vp = vertices(g); vp.first != vp.second; ++vp.first) {
  159. Vertex v = *vp.first;
  160. std::cout &lt;&lt; index[v] &lt;&lt; &quot; &quot;;
  161. }
  162. std::cout &lt;&lt; std::endl;
  163. // ...
  164. return 0;
  165. }
  166. </pre>
  167. The output is:
  168. <pre>
  169. vertices(g) = 0 1 2 3 4
  170. </pre>
  171. <p>&nbsp;
  172. <h2>Accessing the Edge Set</h2>
  173. <p>The set of edges for a graph can be accessed with the <a href="EdgeListGraph.html#sec:edges"><tt>edges()</tt></a>
  174. function of the <a href="EdgeListGraph.html">EdgeListGraph</a> interface.
  175. Similar to the <tt>vertices()</tt> function, this returns a pair of iterators,
  176. but in this case the iterators are <i>edge iterators</i>. Dereferencing an edge
  177. iterator gives an edge object. The <tt>source()</tt> and <tt>target()</tt>
  178. functions return the two vertices that are connected by the edge. Instead of
  179. explicitly creating a <tt>std::pair</tt> for the iterators, this time we will
  180. use the <a href="../../tuple/doc/tuple_users_guide.html#tiers"><tt>boost::tie()</tt></a> helper function.
  181. This handy function can be used to assign the parts of a <tt>std::pair</tt> into
  182. two separate variables, in this case <tt>ei</tt> and <tt>ei_end</tt>. This is
  183. usually more convenient than creating a <tt>std::pair</tt> and is our method of
  184. choice for the BGL.
  185. <p>&nbsp;
  186. <pre>
  187. // ...
  188. int main(int,char*[])
  189. {
  190. // ...
  191. std::cout &lt;&lt; &quot;edges(g) = &quot;;
  192. graph_traits&lt;Graph&gt;::edge_iterator ei, ei_end;
  193. for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
  194. std::cout &lt;&lt; &quot;(&quot; &lt;&lt; index[source(*ei, g)]
  195. &lt;&lt; &quot;,&quot; &lt;&lt; index[target(*ei, g)] &lt;&lt; &quot;) &quot;;
  196. std::cout &lt;&lt; std::endl;
  197. // ...
  198. return 0;
  199. }
  200. </pre>
  201. The output is:
  202. <pre>
  203. edges(g) = (0,1) (0,3) (2,0) (3,2) (2,4) (1,3) (3,4)
  204. </pre>
  205. <p>&nbsp;
  206. <h2>The Adjacency Structure</h2>
  207. <p>In the next few examples we will explore the adjacency structure of the graph
  208. from the point of view of a particular vertex. We will look at the vertices'
  209. in-edges, out-edges, and its adjacent vertices. We will encapsulate this in an
  210. &quot;exercise vertex&quot; function, and apply it to each vertex in the graph.
  211. To demonstrate the STL-interoperability of BGL, we will use the STL <tt>for_each()</tt>
  212. function to iterate through the vertices and apply the function.
  213. <p>&nbsp;
  214. <pre>
  215. //...
  216. int main(int,char*[])
  217. {
  218. //...
  219. std::for_each(vertices(g).first, vertices(g).second,
  220. exercise_vertex&lt;Graph&gt;(g));
  221. return 0;
  222. }
  223. </pre>
  224. <p>We use a functor for <tt>exercise_vertex</tt> instead of just a function
  225. because the graph object will be needed when we access information about each
  226. vertex; using a functor gives us a place to keep a reference to the graph object
  227. during the execution of the <tt>std::for_each()</tt>. Also we template the
  228. functor on the graph type so that it is reusable with different graph classes.
  229. Here is the start of the <tt>exercise_vertex</tt> functor:
  230. <p>&nbsp;
  231. <pre>
  232. template &lt;class Graph&gt; struct exercise_vertex {
  233. exercise_vertex(Graph&amp; g_) : g(g_) {}
  234. //...
  235. Graph&amp; g;
  236. };
  237. </pre>
  238. <p>&nbsp;
  239. <h3>Vertex Descriptors</h3>
  240. <p>The first thing we need to know in order to write the <tt>operator()</tt>
  241. method of the functor is the type for the vertex objects of the graph. The
  242. vertex type will be the parameter to the <tt>operator()</tt> method. To be
  243. precise, we do not deal with actual vertex objects, but rather with <i>vertex
  244. descriptors</i>. Many graph representations (such as adjacency lists) do not
  245. store actual vertex objects, while others do (e.g., pointer-linked graphs). This
  246. difference is hidden underneath the &quot;black-box&quot; of the vertex
  247. descriptor object. The vertex descriptor is something provided by each graph
  248. type that can be used to access information about the graph via the <tt>out_edges()</tt>,
  249. <tt>in_edges()</tt>, <tt>adjacent_vertices()</tt>, and property map functions
  250. that are described in the following sections. The <tt>vertex_descriptor</tt>
  251. type is obtained through the <tt>graph_traits</tt> class. The <tt>typename</tt>
  252. keyword used below is necessary because the type on the left hand side of the
  253. scope <tt>::</tt> operator (the <tt>graph_traits&lt;Graph&gt;</tt> type) is
  254. dependent on a template parameter (the <tt>Graph</tt> type). Here is how we
  255. define the functor's apply method:
  256. <p>&nbsp;
  257. <pre>
  258. template &lt;class Graph&gt; struct exercise_vertex {
  259. //...
  260. typedef typename graph_traits&lt;Graph&gt;
  261. ::vertex_descriptor Vertex;
  262. void operator()(const Vertex&amp; v) const
  263. {
  264. //...
  265. }
  266. //...
  267. };
  268. </pre>
  269. <p>&nbsp;
  270. <h3>Out-Edges, In-Edges, and Edge Descriptors</h3>
  271. <p>The out-edges of a vertex are accessed with the <a href="IncidenceGraph.html#sec:out-edges"><tt>out_edges()</tt></a>
  272. function of the <a href="IncidenceGraph.html">IncidenceGraph</a> interface. The <tt>out_edges()</tt>
  273. function takes two arguments: the first argument is the vertex and the second is
  274. the graph object. The function returns a pair of iterators which provide access
  275. to all of the out-edges of a vertex (similar to how the <tt>vertices()</tt>
  276. function returned a pair of iterators). The iterators are called <i>out-edge
  277. iterators</i> and dereferencing one of these iterators gives an <i>edge
  278. descriptor</i> object. An edge descriptor plays the same kind of role as the
  279. vertex descriptor object, it is a &quot;black box&quot; provided by the graph
  280. type. The following code snippet prints the source-target pairs for each
  281. out-edge of vertex <tt>v</tt>.
  282. <p>&nbsp;
  283. <pre>
  284. template &lt;class Graph&gt; struct exercise_vertex {
  285. //...
  286. void operator()(const Vertex&amp; v) const
  287. {
  288. typedef graph_traits&lt;Graph&gt; GraphTraits;
  289. typename property_map&lt;Graph, vertex_index_t&gt;::type
  290. index = get(vertex_index, g);
  291. std::cout &lt;&lt; &quot;out-edges: &quot;;
  292. typename GraphTraits::out_edge_iterator out_i, out_end;
  293. typename GraphTraits::edge_descriptor e;
  294. for (boost::tie(out_i, out_end) = out_edges(v, g);
  295. out_i != out_end; ++out_i) {
  296. e = *out_i;
  297. Vertex src = source(e, g), targ = target(e, g);
  298. std::cout &lt;&lt; &quot;(&quot; &lt;&lt; index[src] &lt;&lt; &quot;,&quot;
  299. &lt;&lt; index[targ] &lt;&lt; &quot;) &quot;;
  300. }
  301. std::cout &lt;&lt; std::endl;
  302. //...
  303. }
  304. //...
  305. };
  306. </pre>
  307. For vertex 0 the output is:
  308. <pre>
  309. out-edges: (0,1) (0,2) (0,3) (0,4)
  310. </pre>
  311. <p>The <a href="BidirectionalGraph.html#sec:in-edges"><tt>in_edges()</tt></a>
  312. function of the <a href="BidirectionalGraph.html">BidirectionalGraph</a>
  313. interface provides access to all the in-edges of a vertex through <i>in-edge
  314. iterators</i>. The <tt>in_edges()</tt> function is only available for the <tt>adjacency_list</tt>
  315. if <tt>bidirectionalS</tt> is supplied for the <tt>Directed</tt> template
  316. parameter. There is an extra cost in space when <tt>bidirectionalS</tt> is
  317. specified instead of <tt>directedS</tt>.
  318. <p>&nbsp;
  319. <pre>
  320. template &lt;class Graph&gt; struct exercise_vertex {
  321. //...
  322. void operator()(const Vertex&amp; v) const
  323. {
  324. //...
  325. std::cout &lt;&lt; &quot;in-edges: &quot;;
  326. typedef typename graph_traits&lt;Graph&gt; GraphTraits;
  327. typename GraphTraits::in_edge_iterator in_i, in_end;
  328. for (boost::tie(in_i, in_end) = in_edges(v,g);
  329. in_i != in_end; ++in_i) {
  330. e = *in_i;
  331. Vertex src = source(e, g), targ = target(e, g);
  332. std::cout &lt;&lt; &quot;(&quot; &lt;&lt; index[src] &lt;&lt; &quot;,&quot; &lt;&lt; index[targ] &lt;&lt; &quot;) &quot;;
  333. }
  334. std::cout &lt;&lt; std::endl;
  335. //...
  336. }
  337. //...
  338. };
  339. </pre>
  340. For vertex 0 the output is:
  341. <pre>
  342. in-edges: (2,0) (3,0) (4,0)
  343. </pre>
  344. <p>&nbsp;
  345. <h3>Adjacent Vertices</h3>
  346. <p>Given the out-edges of a vertex, the target vertices of these edges are <i>adjacent</i>
  347. to the source vertex. Sometimes an algorithm does not need to look at the edges
  348. of the graph and only cares about the vertices. Therefore the graph interface
  349. also includes the <a href="AdjacencyGraph.html#sec:adjacent-vertices"><tt>adjacent_vertices()</tt></a>
  350. function of the <a href="AdjacencyGraph.html">AdjacencyGraph</a> interface which
  351. provides direct access to the adjacent vertices. This function returns a pair of
  352. <i>adjacency iterators</i>. Dereferencing an adjacency iterator gives a vertex
  353. descriptor for an adjacent vertex.
  354. <p>&nbsp;
  355. <pre>
  356. template &lt;class Graph&gt; struct exercise_vertex {
  357. //...
  358. void operator()(Vertex v) const
  359. {
  360. //...
  361. std::cout &lt;&lt; &quot;adjacent vertices: &quot;;
  362. typename graph_traits&lt;Graph&gt;::adjacency_iterator ai;
  363. typename graph_traits&lt;Graph&gt;::adjacency_iterator ai_end;
  364. for (boost::tie(ai, ai_end) = adjacent_vertices(v, g);
  365. ai != ai_end; ++ai)
  366. std::cout &lt;&lt; index[*ai] &lt;&lt; &quot; &quot;;
  367. std::cout &lt;&lt; std::endl;
  368. }
  369. //...
  370. };
  371. </pre>
  372. For vertex 4 the output is:
  373. <pre>
  374. adjacent vertices: 0 1
  375. </pre>
  376. <p>&nbsp;
  377. <h2>Adding Some Color to your Graph</h2>
  378. <p>BGL attempts to be as flexible as possible in terms of accommodating how
  379. properties are attached to a graph. For instance, a property such as edge weight
  380. may need to be used throughout a graph object's lifespan and therefore it would
  381. be convenient to have the graph object also manage the property storage. On the
  382. other hand, a property like vertex color may only be needed for the duration of
  383. a single algorithm, and it would be better to have the property stored
  384. separately from the graph object. The first kind of property is called an <i>internally
  385. stored property</i> while the second kind is called an <i>externally stored
  386. property</i>. BGL uses a uniform mechanism to access both kinds of properties
  387. inside its graph algorithms called the <i>property map</i> interface, described
  388. in Section <a href="property_map.html">Property Map Concepts</a>. In addition,
  389. the <a href="PropertyGraph.html">PropertyGraph</a> concept defines the interface
  390. for obtaining a property map object for an internally stored property.
  391. <p>The BGL <tt>adjacency_list</tt> class allows users to specify internally
  392. stored properties through plug-in template parameters of the graph class. How to
  393. do this is discussed in detail in Section <a href="using_adjacency_list.html#sec:adjacency-list-properties">Internal
  394. Properties</a>. Externally stored properties can be created in many different
  395. ways, although they are ultimately passed as separate arguments to the graph
  396. algorithms. One straightforward way to store properties is to create an array
  397. indexed by vertex or edge index. In the <tt>adjacency_list</tt> with <tt>vecS</tt>
  398. specified for the <tt>VertexList</tt> template parameter, vertices are
  399. automatically assigned indices, which can be accessed via the property map for
  400. the <tt>vertex_index_t</tt>. Edges are not automatically assigned indices.
  401. However the property mechanism can be used to attach indices to the edges which
  402. can be used to index into other externally stored properties.
  403. <p>In the following example, we construct a graph and apply <a href="dijkstra_shortest_paths.html"><tt>dijkstra_shortest_paths()</tt></a>.
  404. The complete source code for the example is in <a href="../example/dijkstra-example.cpp"><tt>examples/dijkstra-example.cpp</tt></a>.
  405. Dijkstra's algorithm computes the shortest distance from the starting vertex to
  406. every other vertex in the graph.
  407. <p>Dijkstra's algorithm requires that a weight property is associated with each
  408. edge and a distance property with each vertex. Here we use an internal property
  409. for the weight and an external property for the distance. For the weight
  410. property we use the <tt>property</tt> class and specify <tt>int</tt> as the type
  411. used to represent weight values and <tt>edge_weight_t</tt> for the property tag
  412. (which is one of the BGL predefined property tags). The weight property is then
  413. used as a template argument for <tt>adjacency_list</tt>.
  414. <p>The <tt>listS</tt> and <tt>vecS</tt> types are selectors that determine the
  415. data structure used inside the <tt>adjacency_list</tt> (see Section <a href="using_adjacency_list.html#sec:choosing-graph-type">Choosing
  416. the <tt>Edgelist</tt> and <tt>VertexList</tt></a>). The <tt>directedS</tt> type
  417. specifies that the graph should be directed (versus undirected). The following
  418. code shows the specification of the graph type and then the initialization of
  419. the graph. The edges and weights are passed to the graph constructor in the form
  420. of iterators (a pointer qualifies as a <a href="http://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>).
  421. <p>&nbsp;
  422. <pre>
  423. typedef adjacency_list&lt;listS, vecS, directedS,
  424. no_property, property&lt;edge_weight_t, int&gt; &gt; Graph;
  425. typedef graph_traits&lt;Graph&gt;::vertex_descriptor Vertex;
  426. typedef std::pair&lt;int,int&gt; E;
  427. const int num_nodes = 5;
  428. E edges[] = { E(0,2),
  429. E(1,1), E(1,3), E(1,4),
  430. E(2,1), E(2,3),
  431. E(3,4),
  432. E(4,0), E(4,1) };
  433. int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1};
  434. Graph G(edges, edges + sizeof(edges) / sizeof(E), weights, num_nodes);
  435. </pre>
  436. <p>For the external distance property we will use a <tt>std::vector</tt> for
  437. storage. BGL algorithms treat random access iterators as property maps, so we
  438. can just pass the beginning iterator of the distance vector to Dijkstra's
  439. algorithm. Continuing the above example, the following code shows the creation
  440. of the distance vector, the call to Dijkstra's algorithm (implicitly using the
  441. internal edge weight property), and then the output of the results.
  442. <p>&nbsp;
  443. <pre>
  444. // vector for storing distance property
  445. std::vector&lt;int&gt; d(num_vertices(G));
  446. // get the first vertex
  447. Vertex s = *(vertices(G).first);
  448. // invoke variant 2 of Dijkstra's algorithm
  449. dijkstra_shortest_paths(G, s, distance_map(&amp;d[0]));
  450. std::cout &lt;&lt; &quot;distances from start vertex:&quot; &lt;&lt; std::endl;
  451. graph_traits&lt;Graph&gt;::vertex_iterator vi;
  452. for(vi = vertices(G).first; vi != vertices(G).second; ++vi)
  453. std::cout &lt;&lt; &quot;distance(&quot; &lt;&lt; index(*vi) &lt;&lt; &quot;) = &quot;
  454. &lt;&lt; d[*vi] &lt;&lt; std::endl;
  455. std::cout &lt;&lt; std::endl;
  456. </pre>
  457. The output is:
  458. <pre>
  459. distances from start vertex:
  460. distance(0) = 0
  461. distance(1) = 6
  462. distance(2) = 1
  463. distance(3) = 4
  464. distance(4) = 5
  465. </pre>
  466. <p>&nbsp;
  467. <h2>Extending Algorithms with Visitors</h2>
  468. <p>Often times an algorithm in a library <i>almost</i> does what you need, but
  469. not quite. For example, in the previous section we used Dijkstra's algorithm to
  470. calculate the shortest distances to each vertex, but perhaps we also wanted to
  471. record the tree of shortest paths. One way to do this is to record the
  472. predecessor (parent) for each node in the shortest-paths tree.
  473. <p>It would be nice if we could avoid rewriting Dijkstra's algorithm, and just
  474. add that little bit extra needed to record the predecessors <a href="#1">[1]</a>. In the STL, this
  475. kind of extensibility is provided by functors, which are optional parameters to
  476. each algorithm. In the BGL this role is fulfilled by <i>visitors</i>.
  477. <p>A visitor is like a functor, but instead of having just one &quot;apply&quot;
  478. method, it has several. Each of these methods get invoked at certain
  479. well-defined points within the algorithm. The visitor methods are explained in
  480. detail in Section <a href="visitor_concepts.html">Visitor Concepts</a>. The BGL
  481. provides a number of visitors for some common tasks including a predecessor
  482. recording visitor. The user is encouraged to write his or her own visitors as a
  483. way of extending the BGL. Here we will take a quick look at the implementation
  484. and use of the predecessor recorder. Since we will be using the <a href="dijkstra_shortest_paths.html">dijkstra_shortest_paths()</a>
  485. algorithm, the visitor we create must be a <a href="DijkstraVisitor.html">Dijkstra Visitor</a>.
  486. <p>The functionality of the <tt>record_predecessors</tt> visitor is separated
  487. into two parts. For the storage and access of the predecessor property, we will
  488. use a <a href="../../property_map/doc/property_map.html">property map</a>. The
  489. predecessor visitor will then only be responsible for what parent to record. To
  490. implement this, we create a <tt>record_predecessors</tt> class and template it
  491. on the predecessor property map <tt>PredecessorMap</tt>. Since this visitor will
  492. only be filling in one of the visitor methods, we will inherit from <a href="dijkstra_visitor.html"><tt>dijkstra_visitor</tt></a>
  493. which will provide empty methods for the rest. The constructor of the <tt>predecessor_recorder</tt>
  494. will take the property map object and save it away in a data member.
  495. <p>&nbsp;
  496. <pre>
  497. template &lt;class PredecessorMap&gt;
  498. class record_predecessors : public dijkstra_visitor&lt;&gt;
  499. {
  500. public:
  501. record_predecessors(PredecessorMap p)
  502. : m_predecessor(p) { }
  503. template &lt;class Edge, class Graph&gt;
  504. void edge_relaxed(Edge e, Graph&amp; g) {
  505. // set the parent of the target(e) to source(e)
  506. put(m_predecessor, target(e, g), source(e, g));
  507. }
  508. protected:
  509. PredecessorMap m_predecessor;
  510. };
  511. </pre>
  512. <p>The job of recording the predecessors is quite simple. When Dijkstra's
  513. algorithm relaxes an edge (potentially adding it to the shortest-paths tree) we
  514. record the source vertex as the predecessor of the target vertex. Later, if the
  515. edge is relaxed again the predecessor property will be overwritten by the new
  516. predecessor. Here we use the <tt>put()</tt> function associated with the
  517. property map to record the predecessor. The <tt>edge_filter</tt> of the visitor
  518. tells the algorithm when to invoke the <tt>explore()</tt> method. In this case
  519. we only want to be notified about edges in the shortest-paths tree so we specify
  520. <tt>tree_edge_tag</tt>.
  521. <p>As a finishing touch, we create a helper function to make it more convenient
  522. to create predecessor visitors. All BGL visitors have a helper function like
  523. this.
  524. <p>&nbsp;
  525. <pre>
  526. template &lt;class PredecessorMap&gt;
  527. record_predecessors&lt;PredecessorMap&gt;
  528. make_predecessor_recorder(PredecessorMap p) {
  529. return record_predecessors&lt;PredecessorMap&gt;(p);
  530. }
  531. </pre>
  532. <p>We are now ready to use the <tt>record_predecessors</tt> in
  533. Dijkstra's algorithm. Luckily, BGL's Dijkstra's algorithm is already
  534. equipped to handle visitors, so we just pass in our new visitor. In
  535. this example we only need to use one visitor, but the BGL is also
  536. equipped to handle the use of multiple visitors in the same algorithm
  537. (see Section <a href="visitor_concepts.html">Visitor Concepts</a>).
  538. <p>&nbsp;
  539. <pre>
  540. using std::vector;
  541. using std::cout;
  542. using std::endl;
  543. vector&lt;Vertex&gt; p(num_vertices(G), graph_traits&lt;G&gt;::null_vertex()); //the predecessor array
  544. dijkstra_shortest_paths(G, s, distance_map(&amp;d[0]).
  545. visitor(make_predecessor_recorder(&amp;p[0])));
  546. cout &lt;&lt; &quot;parents in the tree of shortest paths:&quot; &lt;&lt; endl;
  547. for(vi = vertices(G).first; vi != vertices(G).second; ++vi) {
  548. cout &lt;&lt; &quot;parent(&quot; &lt;&lt; *vi;
  549. if (p[*vi] == graph_traits&lt;G&gt;::null_vertex())
  550. cout &lt;&lt; &quot;) = no parent&quot; &lt;&lt; endl;
  551. else
  552. cout &lt;&lt; &quot;) = &quot; &lt;&lt; p[*vi] &lt;&lt; endl;
  553. }
  554. </pre>
  555. The output is:
  556. <pre>
  557. parents in the tree of shortest paths:
  558. parent(0) = no parent
  559. parent(1) = 4
  560. parent(2) = 0
  561. parent(3) = 2
  562. parent(4) = 3
  563. </pre>
  564. <br>
  565. <h3>Notes</h3>
  566. <a name="1">[1]</a> The new version of Dijkstra's algorithm now includes
  567. a named parameter for recording predecessors, so a predecessor visitor
  568. is no long necessary, though this still makes for a good example.
  569. <br>
  570. <hr>
  571. <table>
  572. <tr valign="top">
  573. <td nowrap>Copyright © 2000</td>
  574. <td><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>,
  575. Indiana University (<a href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>)</td>
  576. </tr>
  577. </table>
  578. </body>
  579. </html>
  580. <!-- LocalWords: STL BGL cpp vecS bidirectionalS directedS undirectedS hpp vp
  581. -->
  582. <!-- LocalWords: iostream namespace int const num sizeof map ID's gif typedef
  583. -->
  584. <!-- LocalWords: iter ei interoperability struct typename GraphTraits src ai
  585. -->
  586. <!-- LocalWords: targ PropertyGraph Properties property iterator iterators
  587. -->
  588. <!-- LocalWords: VertexList dijkstra listS Edgelist RandomAccessIterator cout
  589. -->
  590. <!-- LocalWords: weightp adjacency tradeoffs undirected MutableGraph indices
  591. -->
  592. <!-- LocalWords: VertexListGraph Dereferencing IndexMap EdgeListGraph functor
  593. -->
  594. <!-- LocalWords: functor's IncidenceGraph dereferencing BidirectionalGraph
  595. -->
  596. <!-- LocalWords: AdjacencyGraph Dijkstra's extensibility functors BGL's endl
  597. -->
  598. <!-- LocalWords: DijkstraVisitor PredecessorMap siek htm Univ Notre
  599. -->