]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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: Depth-First Search</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><A NAME="sec:depth-first-search"></A><img src="figs/python.gif" alt="(Python)"/> | |
19 | <TT>depth_first_search</TT> | |
20 | </H1> | |
21 | ||
22 | <P> | |
23 | <PRE> | |
24 | <i>// named parameter version</i> | |
25 | template <class Graph, class class P, class T, class R> | |
26 | void depth_first_search(Graph& G, | |
27 | const bgl_named_params<P, T, R>& params); | |
28 | ||
29 | <i>// non-named parameter version</i> | |
30 | template <class Graph, class <a href="DFSVisitor.html">DFSVisitor</a>, class ColorMap> | |
31 | void depth_first_search(const Graph& g, DFSVisitor vis, ColorMap color) | |
32 | ||
33 | template <class Graph, class <a href="DFSVisitor.html">DFSVisitor</a>, class ColorMap> | |
34 | void depth_first_search(const Graph& g, DFSVisitor vis, ColorMap color, | |
35 | typename graph_traits<Graph>::vertex_descriptor start) | |
36 | ||
37 | </PRE> | |
38 | ||
39 | <p> | |
40 | The <tt>depth_first_search()</tt> function performs a depth-first | |
41 | traversal of the vertices in a directed graph. When | |
42 | possible, a depth-first traversal chooses a vertex adjacent to the | |
43 | current vertex to visit next. If all adjacent vertices have already | |
44 | been discovered, or there are no adjacent vertices, then the algorithm | |
45 | backtracks to the last vertex that had undiscovered neighbors. Once | |
46 | all reachable vertices have been visited, the algorithm selects from | |
47 | any remaining undiscovered vertices and continues the traversal. The | |
48 | algorithm finishes when all vertices have been visited. Depth-first | |
49 | search is useful for categorizing edges in a graph, and for imposing | |
50 | an ordering on the vertices. Section <a | |
51 | href="./graph_theory_review.html#sec:dfs-algorithm">Depth-First | |
52 | Search</a> describes the various properties of DFS and walks through | |
53 | an example. | |
54 | </p> | |
55 | ||
56 | <p> | |
57 | Similar to BFS, color markers are used to keep track of which vertices | |
58 | have been discovered. White marks vertices that have yet to be | |
59 | discovered, gray marks a vertex that is discovered but still has | |
60 | vertices adjacent to it that are undiscovered. A black vertex is | |
61 | discovered vertex that is not adjacent to any white vertices. | |
62 | <p> | |
63 | ||
64 | <p> | |
65 | The <tt>depth_first_search()</tt> function invokes user-defined | |
66 | actions at certain event-points within the algorithm. This provides a | |
67 | mechanism for adapting the generic DFS algorithm to the many | |
68 | situations in which it can be used. In the pseudo-code below, the | |
69 | event points for DFS are the labels on | |
70 | the right. The user-defined actions must be provided in the form of a | |
71 | visitor object, that is, an object whose type meets the requirements | |
72 | for a <a href="./DFSVisitor.html">DFS Visitor</a>. In the pseudo-code | |
73 | we show the algorithm computing predecessors <i>p</i>, discover time | |
74 | <i>d</i> and finish time <i>t</i>. By default, the | |
75 | <tt>depth_first_search()</tt> function does not compute these | |
76 | properties, however there are pre-defined visitors such as <a | |
77 | href="./predecessor_recorder.html"><tt>predecessor_recorder</tt></a> | |
78 | and <a href="./time_stamper.html"><tt>time_stamper</tt></a> that can | |
79 | be used to do this. | |
80 | </p> | |
81 | ||
82 | <table> | |
83 | <tr> | |
84 | <td valign="top"> | |
85 | <pre> | |
86 | DFS(<i>G</i>) | |
87 | <b>for</b> each vertex <i>u in V</i> | |
88 | <i>color[u] :=</i> WHITE | |
89 | <i>p[u] = u</i> | |
90 | <b>end for</b> | |
91 | <i>time := 0</i> | |
92 | <b>if</b> there is a starting vertex <i>s</i> | |
93 | <b>call</b> DFS-VISIT(<i>G</i>, <i>s</i>) | |
94 | <b>for</b> each vertex <i>u in V</i> | |
95 | <b>if</b> <i>color[u] =</i> WHITE | |
96 | <b>call</b> DFS-VISIT(<i>G</i>, <i>u</i>) | |
97 | <b>end for</b> | |
98 | return (<i>p</i>,<i>d_time</i>,<i>f_time</i>) <br> | |
99 | DFS-VISIT(<i>G</i>, <i>u</i>) | |
100 | <i>color[u] :=</i> GRAY | |
101 | <i>d_time[u] := time := time + 1</i> | |
102 | <b>for</b> each <i>v in Adj[u]</i> | |
103 | <b>if</b> (<i>color[v] =</i> WHITE) | |
104 | <i>p[v] = u</i> | |
105 | <b>call</b> DFS-VISIT(<i>G</i>, <i>v</i>) | |
106 | <b>else if</b> (<i>color[v] =</i> GRAY) | |
107 | <i>...</i> | |
108 | <b>else if</b> (<i>color[v] =</i> BLACK) | |
109 | <i>...</i> | |
110 | <i>...</i> | |
111 | <b>end for</b> | |
112 | <i>color[u] :=</i> BLACK | |
113 | <i>f_time[u] := time := time + 1</i> | |
114 | <pre> | |
115 | </td> | |
116 | <td valign="top"> | |
117 | <pre> | |
118 | - | |
119 | - | |
120 | initialize vertex <i>u</i> | |
121 | - | |
122 | - | |
123 | - | |
124 | - | |
125 | start vertex <i>s</i> | |
126 | - | |
127 | - | |
128 | start vertex <i>u</i> | |
129 | - | |
130 | - | |
131 | - | |
132 | - | |
133 | discover vertex <i>u</i> | |
134 | - | |
135 | examine edge <i>(u,v)</i> | |
136 | - | |
137 | <i>(u,v)</i> is a tree edge | |
138 | - | |
139 | - | |
140 | <i>(u,v)</i> is a back edge | |
141 | - | |
142 | <i>(u,v)</i> is a cross or forward edge | |
143 | - | |
144 | finish edge <i>(u,v)</i> | |
145 | - | |
146 | finish vertex <i>u</i> | |
147 | - | |
148 | </pre> | |
149 | </td> | |
150 | </tr> | |
151 | </table> | |
152 | ||
153 | ||
154 | ||
155 | <H3>Where Defined</H3> | |
156 | ||
157 | <P> | |
158 | <a href="../../../boost/graph/depth_first_search.hpp"><TT>boost/graph/depth_first_search.hpp</TT></a> | |
159 | ||
160 | <h3>Parameters</h3> | |
161 | ||
162 | IN: <tt>Graph& g</tt> | |
163 | <blockquote> | |
164 | A directed graph. The graph type must | |
165 | be a model of <a href="./IncidenceGraph.html">Incidence Graph</a> | |
166 | and <a href="./VertexListGraph.html">Vertex List Graph</a>.<br> | |
167 | ||
168 | <b>Python</b>: The parameter is named <tt>graph</tt>. | |
169 | </blockquote> | |
170 | ||
171 | ||
172 | <h3>Named Parameters</h3> | |
173 | ||
174 | IN: <tt>visitor(DFSVisitor vis)</tt> | |
175 | <blockquote> | |
176 | A visitor object that is invoked inside the algorithm at the | |
177 | event-points specified by the <a href="./DFSVisitor.html">DFS | |
178 | Visitor</a> concept. The visitor object is passed by value <a | |
179 | href="#1">[1]</a>. <br> <b>Default:</b> | |
180 | <tt>dfs_visitor<null_visitor></tt><br> | |
181 | ||
182 | <b>Python</b>: The parameter should be an object that derives from | |
183 | the <a href="DFSVisitor.html#python"><tt>DFSVisitor</tt></a> type of | |
184 | the graph. | |
185 | </blockquote> | |
186 | ||
187 | UTIL/OUT: <tt>color_map(ColorMap color)</tt> | |
188 | <blockquote> | |
189 | This is used by the algorithm to keep track of its progress through | |
190 | the graph. The type <tt>ColorMap</tt> must be a model of <a | |
191 | href="../../property_map/doc/ReadWritePropertyMap.html">Read/Write | |
192 | Property Map</a> and its key type must be the graph's vertex | |
193 | descriptor type and the value type of the color map must model | |
194 | <a href="./ColorValue.html">ColorValue</a>.<br> | |
195 | <b>Default:</b> an <a | |
196 | href="../../property_map/doc/iterator_property_map.html"> | |
197 | </tt>iterator_property_map</tt></a> created from a | |
198 | <tt>std::vector</tt> of <tt>default_color_type</tt> of size | |
199 | <tt>num_vertices(g)</tt> and using the <tt>i_map</tt> for the index | |
200 | map.<br> | |
201 | ||
202 | <b>Python</b>: The color map must be a <tt>vertex_color_map</tt> for | |
203 | the graph. | |
204 | </blockquote> | |
205 | ||
206 | IN: <tt>root_vertex(typename | |
207 | graph_traits<VertexListGraph>::vertex_descriptor start)</tt> | |
208 | <blockquote> | |
209 | This specifies the vertex that the depth-first search should | |
210 | originate from. The type is the type of a vertex descriptor for the | |
211 | given graph.<br> | |
212 | <b>Default:</b> <tt>*vertices(g).first</tt><br> | |
213 | </blockquote> | |
214 | ||
215 | IN: <tt>vertex_index_map(VertexIndexMap i_map)</tt> | |
216 | <blockquote> | |
217 | This maps each vertex to an integer in the range <tt>[0, | |
218 | num_vertices(g))</tt>. This parameter is only necessary when the | |
219 | default color property map is used. The type <tt>VertexIndexMap</tt> | |
220 | must be a model of <a | |
221 | href="../../property_map/doc/ReadablePropertyMap.html">Readable Property | |
222 | Map</a>. The value type of the map must be an integer type. The | |
223 | vertex descriptor type of the graph needs to be usable as the key | |
224 | type of the map.<br> | |
225 | ||
226 | <b>Default:</b> <tt>get(vertex_index, g)</tt>. | |
227 | Note: if you use this default, make sure your graph has | |
228 | an internal <tt>vertex_index</tt> property. For example, | |
229 | <tt>adjacency_list</tt> with <tt>VertexList=listS</tt> does | |
230 | not have an internal <tt>vertex_index</tt> property.<br> | |
231 | ||
232 | <b>Python</b>: Unsupported parameter. | |
233 | </blockquote> | |
234 | ||
235 | <P> | |
236 | ||
237 | <H3><A NAME="SECTION001340300000000000000"> | |
238 | Complexity</A> | |
239 | </H3> | |
240 | ||
241 | <P> | |
242 | The time complexity is <i>O(E + V)</i>. | |
243 | ||
244 | <P> | |
245 | ||
246 | <h3>Visitor Event Points</h3> | |
247 | ||
248 | <ul> | |
249 | ||
250 | <li><b><tt>vis.initialize_vertex(s, g)</tt></b> is invoked on every | |
251 | vertex of the graph before the start of the graph search. | |
252 | ||
253 | <li><b><tt>vis.start_vertex(s, g)</tt></b> is invoked on the source | |
254 | vertex once before the start of the search. | |
255 | ||
256 | <li><b><tt>vis.discover_vertex(u, g)</tt></b> is invoked when a vertex | |
257 | is encountered for the first time. | |
258 | ||
259 | <li><b><tt>vis.examine_edge(e, g)</tt></b> is invoked on every out-edge | |
260 | of each vertex after it is discovered. | |
261 | ||
262 | <li><b><tt>vis.tree_edge(e, g)</tt></b> is invoked on each edge as it | |
263 | becomes a member of the edges that form the search tree. If you | |
264 | wish to record predecessors, do so at this event point. | |
265 | ||
266 | <li><b><tt>vis.back_edge(e, g)</tt></b> is invoked on the back edges in | |
267 | the graph. | |
268 | ||
269 | <li><b><tt>vis.forward_or_cross_edge(e, g)</tt></b> is invoked on | |
270 | forward or cross edges in the graph. In an undirected graph this | |
271 | method is never called. | |
272 | ||
273 | <li><b><tt>vis.finish_edge(e, g)</tt></b> is invoked on the non-tree edges in | |
274 | the graph as well as on each tree edge after its target vertex is finished. | |
275 | ||
276 | <li><b><tt>vis.finish_vertex(u, g)</tt></b> is invoked on a vertex after | |
277 | all of its out edges have been added to the search tree and all of | |
278 | the adjacent vertices have been discovered (but before their | |
279 | out-edges have been examined). | |
280 | ||
281 | </ul> | |
282 | ||
283 | ||
284 | <H3>Example</H3> | |
285 | ||
286 | <P> | |
287 | The example in <a href="../example/dfs-example.cpp"> | |
288 | <TT>examples/dfs-example.cpp</TT></a> shows DFS applied to the graph in | |
289 | <A HREF="./graph_theory_review.html#fig:dfs-example">Figure 1</A>. | |
290 | ||
291 | <h3>See Also</h3> | |
292 | ||
293 | <a href="./depth_first_visit.html"><tt>depth_first_visit</tt></a> | |
294 | <a href="./undirected_dfs.html"><tt>undirected_dfs</tt></a> | |
295 | ||
296 | <h3>Notes</h3> | |
297 | ||
298 | <p><a name="1">[1]</a> | |
299 | Since the visitor parameter is passed by value, if your visitor | |
300 | contains state then any changes to the state during the algorithm | |
301 | will be made to a copy of the visitor object, not the visitor object | |
302 | passed in. Therefore you may want the visitor to hold this state by | |
303 | pointer or reference. | |
304 | ||
305 | <br> | |
306 | <HR> | |
307 | <TABLE> | |
308 | <TR valign=top> | |
309 | <TD nowrap>Copyright © 2000-2001</TD><TD> | |
310 | <A HREF="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</A>, | |
311 | Indiana University (<A | |
312 | HREF="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</A>)<br> | |
313 | <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> | |
314 | <A HREF="http://www.osl.iu.edu/~lums">Andrew Lumsdaine</A>, | |
315 | Indiana University (<A | |
316 | HREF="mailto:lums@osl.iu.edu">lums@osl.iu.edu</A>) | |
317 | </TD></TR></TABLE> | |
318 | ||
319 | </BODY> | |
320 | </HTML> |