bundles.html 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2. <html>
  3. <!--
  4. Copyright Doug Gregor 2004. Use, modification and
  5. distribution is subject to the Boost Software License, Version
  6. 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. http://www.boost.org/LICENSE_1_0.txt)
  8. For more information, see http://www.boost.org
  9. -->
  10. <head>
  11. <title>Bundled Properties</title>
  12. </head>
  13. <body BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
  14. ALINK="#ff0000">
  15. <IMG SRC="../../../boost.png"
  16. ALT="C++ Boost" width="277" height="86"/>
  17. <h1>Bundled Properties</h1>
  18. <p>Class templates <code><a
  19. href="adjacency_list.html">adjacency_list</a></code> and
  20. <code><a href="adjacency_matrix.html">adjacency_matrix</a></code> support
  21. the introduction of named properties via <a
  22. href="using_adjacency_list.html#sec:adjacency-list-properties">internal
  23. properties</a>. However, this method is cumbersome in many uses,
  24. where it would be more intuitive to just specify a structure or
  25. class that contains internal properties for edges or
  26. vertices. Bundled properties allow one to use
  27. <code>adjacency_list</code> and <code>adjacency_matrix</code> in this
  28. manner, providing a simple
  29. way to introduce and access any number of internal properties
  30. for vertices and edges.</p>
  31. <p>One can introduce bundled properties into an
  32. either graph type by providing a user-defined class
  33. type for the <code>VertexProperties</code> or
  34. <code>EdgeProperties</code> template arguments. The user-defined
  35. class may alternatively be placed at the end of a
  36. <code>property</code> list, replacing the (implicit)
  37. <code>boost::no_property</code> argument.</p>
  38. <h2>Example: Route planning</h2>
  39. <p>Consider the implementation of a simple route planner that
  40. should find the shortest directions from one city to another
  41. via a set of highways. The vertices of the graph are cities,
  42. and we may wish to store several bits of information about the
  43. city within each vertex:</p>
  44. <pre>
  45. struct City
  46. {
  47. string name;
  48. int population;
  49. vector&lt;int&gt; zipcodes;
  50. };
  51. </pre>
  52. <p>
  53. The edges in the graph represent highways, which also have several interesting
  54. attributes:
  55. </p>
  56. <pre>
  57. struct Highway
  58. {
  59. string name;
  60. double miles;
  61. int speed_limit;
  62. int lanes;
  63. bool divided;
  64. };
  65. </pre>
  66. <p>With bundled properties, we can directly use the <code>City</code> and
  67. <code>Highway</code> structures to define the graph:</p>
  68. <pre>
  69. typedef boost::adjacency_list&lt;
  70. boost::listS, boost::vecS, boost::bidirectionalS,
  71. City, Highway&gt;
  72. Map;
  73. </pre>
  74. <p>Without bundled properties, translating this example directly
  75. into an instantiation of <code>adjacency_list</code> would
  76. involve several custom properties and would result in a type
  77. like this:</p>
  78. <pre>
  79. typedef boost::adjacency_list&lt;
  80. boost::listS, boost::vecS, boost::bidirectionalS,
  81. // Vertex properties
  82. boost::property&lt;boost::vertex_name_t, std::string,
  83. boost::property&lt;population_t, int,
  84. boost::property&lt;zipcodes_t, std::vector&lt;int&gt; &gt; &gt; &gt;,
  85. // Edge properties
  86. boost::property&lt;boost::edge_name_t, std::string,
  87. boost::property&lt;boost::edge_weight_t, double,
  88. boost::property&lt;edge_speed_limit_t, int,
  89. boost::property&lt;edge_lanes_t, int,
  90. boost::property&lt;edge_divided, bool&gt; &gt; &gt; &gt; &gt; &gt;
  91. Map;
  92. </pre>
  93. <p>
  94. Bundling vertex and edge properties greatly simplifies the declaration of
  95. graphs.
  96. </p>
  97. <p>
  98. In addition to vertex and edge bundles, we can also bundle properties of the
  99. graph itself. Suppopse we extend the application to include a portfolio of
  100. route-planning maps for different countries. In addition to the <code>City</code>
  101. and <code>Highway</code> bundles above, we can declare a graph bundle,
  102. <code>Country</Code>.
  103. </p>
  104. <pre>
  105. struct Country {
  106. string name;
  107. bool use_right; // Drive on the left or right
  108. bool use_metric; // mph or km/h
  109. };
  110. </pre>
  111. <p>The graph would now be declared as:</p>
  112. <pre>
  113. <pre>
  114. typedef boost::adjacency_list&lt;
  115. boost::listS, boost::vecS, boost::bidirectionalS,
  116. City, Highway, Country&gt;
  117. Map;
  118. </pre>
  119. </pre>
  120. <h2>Accessing bundled properties</h2>
  121. <p>To access a bundled property for a particular edge or vertex,
  122. subscript your graph with the descriptor of the edge or vertex
  123. whose bundled property you wish to access. For instance:</p>
  124. <pre>
  125. Map map; // load the map
  126. Map::vertex_descriptor v = *vertices(map).first;
  127. map[v].name = "Troy";
  128. map[v].population = 49170;
  129. map[v].zipcodes.push_back(12180);
  130. Map::edge_descriptor e = *out_edges(v, map).first;
  131. map[e].name = "I-87";
  132. map[e].miles = 10.;
  133. map[e].speed_limit = 65;
  134. map[e].lanes = 4;
  135. map[e].divided = true;
  136. </pre>
  137. <p>
  138. The graph bundle, since it does not correspond to a vertex or edge descripor
  139. is accessed using the graph_bundle object as a key.
  140. </p>
  141. <pre>
  142. map[graph_bundle].name = "United States";
  143. map[graph_bundle].use_right = true;
  144. map[graph_bundle].use_metric = false;
  145. </pre>
  146. <h2>Properties maps from bundled properties</h2>
  147. <p>Often one needs to create a property map from an internal
  148. property for use in a generic algorithm. For instance, using the
  149. graph without bundled properties we might invoke <a
  150. href="dijkstra_shortest_paths.html">Dijkstra's shortest
  151. paths</a> algorithm like this:</p>
  152. <pre>
  153. vector&lt;double&gt; distances(num_vertices(map));
  154. dijkstra_shortest_paths(map, from,
  155. weight_map(get(edge_length, map))
  156. .distance_map(make_iterator_property_map(distances.begin(),
  157. get(vertex_index, map))));
  158. </pre>
  159. <p>With bundled properties, we can just pass a <em>member pointer</em>
  160. as the property for <code>get</code>. The equivalent example using bundled
  161. properties is:</p>
  162. <pre>
  163. vector&lt;double&gt; distances(num_vertices(map));
  164. dijkstra_shortest_paths(map, from,
  165. weight_map(get(<font color="#ff0000">&amp;Highway::miles</font>, map))
  166. .distance_map(make_iterator_property_map(distances.begin(),
  167. get(vertex_index, map))));
  168. </pre>
  169. <p>The type of the returned property map is <code>property_map&lt;Map, double Highway::*&gt;::type</code>
  170. or <code>property_map&lt;Map, double Highway::*&gt;::const_type</code>, depending on whether the graph
  171. <code>map</code> is non-constant or constant.
  172. <p> You may also access the entire vertex or edge bundle as a property map
  173. using the <code>vertex_bundle</code> or <code>edge_bundle</code> properties,
  174. respectively. For instance, the property map returned by <code>get(vertex_bundle, map)</code> is
  175. an <a href="../../property_map/doc/LvaluePropertyMap.html">Lvalue Property Map</a> providing access to the
  176. <code>City</code> values stored in each vertex.
  177. <h2>Property maps for a graph bundle</h2>
  178. There is currently no support for creating property maps from the bundled
  179. properties of a graph.
  180. <h2>Getting the type of bundled properties</h2>
  181. <p>To get the type of the vertex or edge bundle for a given graph
  182. type <tt>Graph</tt>, you can use the trait
  183. classes <tt>vertex_bundle_type</tt>
  184. and <tt>edge_bundle_type</tt>. The
  185. type <tt>vertex_bundle_type&lt;Graph&gt;::type</tt> will be the
  186. type bundled with vertices (or <tt>no_vertex_bundle</tt> if the
  187. graph supports bundles but no vertex bundle
  188. exists). Likewise, <tt>edge_bundle_type&lt;Graph&gt;::type</tt>
  189. will be the type bundled with edges (or <tt>no_edge_bundle</tt> if
  190. no edge bundle exists).</p>
  191. <h2>Compatibility</h2> <p>Bundled properties will only work
  192. properly on compilers that support class template partial
  193. specialization.</p>
  194. <hr>
  195. Copyright &copy; 2004 <a href="http://www.boost.org/people/doug_gregor.html">Doug Gregor</a>.
  196. <address><a href="mailto:gregod@cs.rpi.edu"></a></address>
  197. <!-- Created: Fri May 7 09:59:21 EDT 2004 -->
  198. <!-- hhmts start -->
  199. Last modified: Fri May 7 10:56:01 EDT 2004
  200. <!-- hhmts end -->
  201. </body>
  202. </html>