• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
25template &lt;class Graph, class class P, class T, class R&gt;
26void depth_first_search(Graph&amp; G,
27  const bgl_named_params&lt;P, T, R&gt;&amp; params);
28
29<i>// non-named parameter version</i>
30template &lt;class Graph, class <a href="DFSVisitor.html">DFSVisitor</a>, class ColorMap&gt;
31void depth_first_search(const Graph&amp; g, DFSVisitor vis, ColorMap color)
32
33template &lt;class Graph, class <a href="DFSVisitor.html">DFSVisitor</a>, class ColorMap&gt;
34void depth_first_search(const Graph&amp; g, DFSVisitor vis, ColorMap color,
35                        typename graph_traits&lt;Graph&gt;::vertex_descriptor start)
36
37</PRE>
38
39<p>
40The <tt>depth_first_search()</tt> function performs a depth-first
41traversal of the vertices in a directed graph.  When
42possible, a depth-first traversal chooses a vertex adjacent to the
43current vertex to visit next. If all adjacent vertices have already
44been discovered, or there are no adjacent vertices, then the algorithm
45backtracks to the last vertex that had undiscovered neighbors. Once
46all reachable vertices have been visited, the algorithm selects from
47any remaining undiscovered vertices and continues the traversal. The
48algorithm finishes when all vertices have been visited. Depth-first
49search is useful for categorizing edges in a graph, and for imposing
50an ordering on the vertices. Section <a
51href="./graph_theory_review.html#sec:dfs-algorithm">Depth-First
52Search</a> describes the various properties of DFS and walks through
53an example.
54</p>
55
56<p>
57Similar to BFS, color markers are used to keep track of which vertices
58have been discovered. White marks vertices that have yet to be
59discovered, gray marks a vertex that is discovered but still has
60vertices adjacent to it that are undiscovered. A black vertex is
61discovered vertex that is not adjacent to any white vertices.
62<p>
63
64<p>
65The <tt>depth_first_search()</tt> function invokes user-defined
66actions at certain event-points within the algorithm. This provides a
67mechanism for adapting the generic DFS algorithm to the many
68situations in which it can be used.  In the pseudo-code below, the
69event points for DFS are the labels on
70the right. The user-defined actions must be provided in the form of a
71visitor object, that is, an object whose type meets the requirements
72for a <a href="./DFSVisitor.html">DFS Visitor</a>. In the pseudo-code
73we 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
76properties, however there are pre-defined visitors such as <a
77href="./predecessor_recorder.html"><tt>predecessor_recorder</tt></a>
78and <a href="./time_stamper.html"><tt>time_stamper</tt></a> that can
79be used to do this.
80</p>
81
82<table>
83<tr>
84<td valign="top">
85<pre>
86DFS(<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>
99DFS-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-
120initialize vertex <i>u</i>
121-
122-
123-
124-
125start vertex <i>s</i>
126-
127-
128start vertex <i>u</i>
129-
130-
131-
132-
133discover vertex <i>u</i>
134-
135examine 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-
144finish edge <i>(u,v)</i>
145-
146finish 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
162IN: <tt>Graph&amp; 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
174IN: <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&lt;null_visitor&gt;</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
187UTIL/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
206IN: <tt>root_vertex(typename
207graph_traits&lt;VertexListGraph&gt;::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
215IN: <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">
238Complexity</A>
239</H3>
240
241<P>
242The 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>
287The 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 &copy; 2000-2001</TD><TD>
310<A HREF="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</A>,
311Indiana University (<A
312HREF="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="https://homes.cs.washington.edu/~al75">Andrew Lumsdaine</A>,
315Indiana University (<A
316HREF="mailto:lums@osl.iu.edu">lums@osl.iu.edu</A>)
317</TD></TR></TABLE>
318
319</BODY>
320</HTML>
321