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