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