constructing_algorithms.html 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <HTML>
  2. <!--
  3. Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 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>Boost Graph Library: Constructing Graph Algorithms</Title>
  10. <BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
  11. ALINK="#ff0000">
  12. <IMG SRC="../../../boost.png"
  13. ALT="C++ Boost" width="277" height="86">
  14. <BR Clear>
  15. <H1>Constructing graph algorithms with BGL</H1>
  16. <P>
  17. The <I>main</I> goal of BGL is not to provide a nice graph class, or
  18. to provide a comprehensive set of reusable graph algorithms (though
  19. these are goals). The main goal of BGL is to encourage others to
  20. write reusable graph algorithms. By reusable we mean maximally
  21. reusable. Generic programming is a methodology for making algorithms
  22. maximally reusable, and in this section we will discuss how to apply
  23. generic programming to constructing graph algorithms.
  24. <P>
  25. To illustrate the generic programming process we will step though the
  26. construction of a graph coloring algorithm. The graph coloring problem
  27. (or more specifically, the vertex coloring problem) is to label each
  28. vertex in a graph <i>G</i> with a color such that no two adjacent
  29. vertices are labeled with the same color and such that the minimum
  30. number of colors are used. In general, the graph coloring problem is
  31. NP-complete, and therefore it is impossible to find an optimal
  32. solution in a reasonable amount of time. However, there are many
  33. algorithms that use heuristics to find colorings that are close to the
  34. minimum.
  35. <P>
  36. The particular algorithm we present here is based on the linear time
  37. <TT>SEQ</TT> subroutine that is used in the estimation of sparse
  38. Jacobian and Hessian matrices&nbsp;[<A
  39. HREF="bibliography.html#curtis74:_jacob">9</A>,<A
  40. HREF="bibliography.html#coleman84:_estim_jacob">7</A>,<A
  41. HREF="bibliography.html#coleman85:_algor">6</A>]. This algorithm
  42. visits all of the vertices in the graph according to the order defined
  43. by the input order. At each vertex the algorithm marks the colors of
  44. the adjacent vertices, and then chooses the smallest unmarked color
  45. for the color of the current vertex. If all of the colors are already
  46. marked, a new color is created. A color is considered marked if its
  47. mark number is equal to the current vertex number. This saves the
  48. trouble of having to reset the marks for each vertex. The
  49. effectiveness of this algorithm is highly dependent on the input
  50. vertex order. There are several ordering algorithms, including the
  51. <I>largest-first</I>&nbsp;[<A HREF="bibliography.html#welsch67">31</A>],
  52. <I>smallest-last</I>&nbsp;[<a
  53. href="bibliography.html#matula72:_graph_theory_computing">29</a>], and
  54. <I>incidence degree</I>&nbsp;[<a
  55. href="bibliography.html#brelaz79:_new">32</a>] algorithms, which
  56. improve the effectiveness of this coloring algorithm.
  57. <P>
  58. The first decision to make when constructing a generic graph algorithm
  59. is to decide what graph operations are necessary for implementing the
  60. algorithm, and which graph concepts the operations map to. In this
  61. algorithm we will need to traverse through all of the vertices to
  62. intialize the vertex colors. We also need to access the adjacent
  63. vertices. Therefore, we will choose the <a
  64. href="./VertexListGraph.html">VertexListGraph</a> concept because it
  65. is the minimum concept that includes these operations. The graph type
  66. will be parameterized in the template function for this algorithm. We
  67. do not restrict the graph type to a particular graph class, such as
  68. the BGL <a href="./adjacency_list.html"><TT>adjacency_list</TT></a>,
  69. for this would drastically limit the reusability of the algorithm (as
  70. most algorithms written to date are). We do restrict the graph type to
  71. those types that model <a
  72. href="./VertexListGraph.html">VertexListGraph</a>. This is enforced by
  73. the use of those graph operations in the algorithm, and furthermore by
  74. our explicit requirement added as a concept check with
  75. <TT>BOOST_CONCEPT_ASSERT()</TT> (see Section <A
  76. HREF="../../concept_check/concept_check.htm">Concept
  77. Checking</A> for more details about concept checking).
  78. <P>
  79. Next we need to think about what vertex or edge properties will be
  80. used in the algorithm. In this case, the only property is vertex
  81. color. The most flexible way to specify access to vertex color is to
  82. use the propery map interface. This gives the user of the
  83. algorithm the ability to decide how they want to store the properties.
  84. Since we will need to both read and write the colors we specify the
  85. requirements as <a
  86. href="../../property_map/doc/ReadWritePropertyMap.html">ReadWritePropertyMap</a>. The
  87. <TT>key_type</TT> of the color map must be the
  88. <TT>vertex_descriptor</TT> from the graph, and the <TT>value_type</TT>
  89. must be some kind of integer. We also specify the interface for the
  90. <TT>order</TT> parameter as a property map, in this case a <a
  91. href="../../property_map/doc/ReadablePropertyMap.html">ReadablePropertyMap</a>. For
  92. order, the <TT>key_type</TT> is an integer offset and the
  93. <TT>value_type</TT> is a <TT>vertex_descriptor</TT>. Again we enforce
  94. these requirements with concept checks. The return value of this
  95. algorithm is the number of colors that were needed to color the graph,
  96. hence the return type of the function is the graph's
  97. <TT>vertices_size_type</TT>. The following code shows the interface for our
  98. graph algorithm as a template function, the concept checks, and some
  99. typedefs. The implementation is straightforward, the only step not
  100. discussed above is the color initialization step, where we set the
  101. color of all the vertices to "uncolored."
  102. <P>
  103. <PRE>
  104. namespace boost {
  105. template &lt;class VertexListGraph, class Order, class Color&gt;
  106. typename graph_traits&lt;VertexListGraph&gt;::vertices_size_type
  107. sequential_vertex_color_ting(const VertexListGraph&amp; G,
  108. Order order, Color color)
  109. {
  110. typedef graph_traits&lt;VertexListGraph&gt; GraphTraits;
  111. typedef typename GraphTraits::vertex_descriptor vertex_descriptor;
  112. typedef typename GraphTraits::vertices_size_type size_type;
  113. typedef typename property_traits&lt;Color&gt;::value_type ColorType;
  114. typedef typename property_traits&lt;Order&gt;::value_type OrderType;
  115. BOOST_CONCEPT_ASSERT(( VertexListGraphConcept&lt;VertexListGraph&gt; ));
  116. BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept&lt;Color, vertex_descriptor&gt; ));
  117. BOOST_CONCEPT_ASSERT(( IntegerConcept&lt;ColorType&gt; ));
  118. BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept&lt;Order, size_type&gt; ));
  119. BOOST_STATIC_ASSERT((is_same&lt;OrderType, vertex_descriptor&gt;::value));
  120. size_type max_color = 0;
  121. const size_type V = num_vertices(G);
  122. std::vector&lt;size_type&gt;
  123. mark(V, numeric_limits_max(max_color));
  124. typename GraphTraits::vertex_iterator v, vend;
  125. for (boost::tie(v, vend) = vertices(G); v != vend; ++v)
  126. color[*v] = V - 1; // which means "not colored"
  127. for (size_type i = 0; i &lt; V; i++) {
  128. vertex_descriptor current = order[i];
  129. // mark all the colors of the adjacent vertices
  130. typename GraphTraits::adjacency_iterator ai, aend;
  131. for (boost::tie(ai, aend) = adjacent_vertices(current, G); ai != aend; ++ai)
  132. mark[color[*ai]] = i;
  133. // find the smallest color unused by the adjacent vertices
  134. size_type smallest_color = 0;
  135. while (smallest_color &lt; max_color &amp;&amp; mark[smallest_color] == i)
  136. ++smallest_color;
  137. // if all the colors are used up, increase the number of colors
  138. if (smallest_color == max_color)
  139. ++max_color;
  140. color[current] = smallest_color;
  141. }
  142. return max_color;
  143. }
  144. } // namespace boost
  145. </PRE>
  146. <P>
  147. <br>
  148. <HR>
  149. <TABLE>
  150. <TR valign=top>
  151. <TD nowrap>Copyright &copy; 2000-2001</TD><TD>
  152. <A HREF="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</A>,
  153. Indiana University (<A
  154. HREF="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</A>)<br>
  155. <A HREF="http://www.boost.org/people/liequan_lee.htm">Lie-Quan Lee</A>, Indiana University (<A HREF="mailto:llee@cs.indiana.edu">llee@cs.indiana.edu</A>)<br>
  156. <A HREF="https://homes.cs.washington.edu/~al75">Andrew Lumsdaine</A>,
  157. Indiana University (<A
  158. HREF="mailto:lums@osl.iu.edu">lums@osl.iu.edu</A>)
  159. </TD></TR></TABLE>
  160. </BODY>
  161. </HTML>