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 <class Graph, class class P, class T, class R> 26void depth_first_search(Graph& G, 27 const bgl_named_params<P, T, R>& params); 28 29<i>// non-named parameter version</i> 30template <class Graph, class <a href="DFSVisitor.html">DFSVisitor</a>, class ColorMap> 31void depth_first_search(const Graph& g, DFSVisitor vis, ColorMap color) 32 33template <class Graph, class <a href="DFSVisitor.html">DFSVisitor</a>, class ColorMap> 34void depth_first_search(const Graph& g, DFSVisitor vis, ColorMap color, 35 typename graph_traits<Graph>::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& 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<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 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<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 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 © 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