Chris@16
|
1 //
|
Chris@16
|
2 //=======================================================================
|
Chris@16
|
3 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
Chris@16
|
4 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
Chris@16
|
5 //
|
Chris@16
|
6 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
7 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
8 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 //=======================================================================
|
Chris@16
|
10 //
|
Chris@16
|
11 #ifndef BOOST_GRAPH_UNDIRECTED_DFS_HPP
|
Chris@16
|
12 #define BOOST_GRAPH_UNDIRECTED_DFS_HPP
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/graph/depth_first_search.hpp>
|
Chris@16
|
15 #include <vector>
|
Chris@16
|
16 #include <boost/concept/assert.hpp>
|
Chris@16
|
17
|
Chris@16
|
18 namespace boost {
|
Chris@16
|
19
|
Chris@16
|
20 namespace detail {
|
Chris@16
|
21
|
Chris@16
|
22 // Define BOOST_RECURSIVE_DFS to use older, recursive version.
|
Chris@16
|
23 // It is retained for a while in order to perform performance
|
Chris@16
|
24 // comparison.
|
Chris@16
|
25 #ifndef BOOST_RECURSIVE_DFS
|
Chris@16
|
26
|
Chris@16
|
27 template <typename IncidenceGraph, typename DFSVisitor,
|
Chris@16
|
28 typename VertexColorMap, typename EdgeColorMap>
|
Chris@16
|
29 void undir_dfv_impl
|
Chris@16
|
30 (const IncidenceGraph& g,
|
Chris@16
|
31 typename graph_traits<IncidenceGraph>::vertex_descriptor u,
|
Chris@16
|
32 DFSVisitor& vis,
|
Chris@16
|
33 VertexColorMap vertex_color,
|
Chris@16
|
34 EdgeColorMap edge_color)
|
Chris@16
|
35 {
|
Chris@16
|
36 BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept<IncidenceGraph> ));
|
Chris@16
|
37 BOOST_CONCEPT_ASSERT(( DFSVisitorConcept<DFSVisitor, IncidenceGraph> ));
|
Chris@16
|
38 typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
|
Chris@16
|
39 typedef typename graph_traits<IncidenceGraph>::edge_descriptor Edge;
|
Chris@16
|
40 BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept<VertexColorMap,Vertex> ));
|
Chris@16
|
41 BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept<EdgeColorMap,Edge> ));
|
Chris@16
|
42 typedef typename property_traits<VertexColorMap>::value_type ColorValue;
|
Chris@16
|
43 typedef typename property_traits<EdgeColorMap>::value_type EColorValue;
|
Chris@16
|
44 BOOST_CONCEPT_ASSERT(( ColorValueConcept<ColorValue> ));
|
Chris@16
|
45 BOOST_CONCEPT_ASSERT(( ColorValueConcept<EColorValue> ));
|
Chris@16
|
46 typedef color_traits<ColorValue> Color;
|
Chris@16
|
47 typedef color_traits<EColorValue> EColor;
|
Chris@16
|
48 typedef typename graph_traits<IncidenceGraph>::out_edge_iterator Iter;
|
Chris@16
|
49 typedef std::pair<Vertex, std::pair<boost::optional<Edge>, std::pair<Iter, Iter> > > VertexInfo;
|
Chris@16
|
50
|
Chris@16
|
51 std::vector<VertexInfo> stack;
|
Chris@16
|
52
|
Chris@16
|
53 put(vertex_color, u, Color::gray());
|
Chris@16
|
54 vis.discover_vertex(u, g);
|
Chris@16
|
55 stack.push_back(std::make_pair(u, std::make_pair(boost::optional<Edge>(), out_edges(u, g))));
|
Chris@16
|
56 while (!stack.empty()) {
|
Chris@16
|
57 VertexInfo& back = stack.back();
|
Chris@16
|
58 u = back.first;
|
Chris@16
|
59 boost::optional<Edge> src_e = back.second.first;
|
Chris@16
|
60 Iter ei = back.second.second.first, ei_end = back.second.second.second;
|
Chris@16
|
61 stack.pop_back();
|
Chris@16
|
62 while (ei != ei_end) {
|
Chris@16
|
63 Vertex v = target(*ei, g);
|
Chris@16
|
64 vis.examine_edge(*ei, g);
|
Chris@16
|
65 ColorValue v_color = get(vertex_color, v);
|
Chris@16
|
66 EColorValue uv_color = get(edge_color, *ei);
|
Chris@16
|
67 put(edge_color, *ei, EColor::black());
|
Chris@16
|
68 if (v_color == Color::white()) {
|
Chris@16
|
69 vis.tree_edge(*ei, g);
|
Chris@16
|
70 src_e = *ei;
|
Chris@16
|
71 stack.push_back(std::make_pair(u, std::make_pair(src_e, std::make_pair(++ei, ei_end))));
|
Chris@16
|
72 u = v;
|
Chris@16
|
73 put(vertex_color, u, Color::gray());
|
Chris@16
|
74 vis.discover_vertex(u, g);
|
Chris@16
|
75 boost::tie(ei, ei_end) = out_edges(u, g);
|
Chris@16
|
76 } else if (v_color == Color::gray()) {
|
Chris@16
|
77 if (uv_color == EColor::white()) vis.back_edge(*ei, g);
|
Chris@16
|
78 call_finish_edge(vis, *ei, g);
|
Chris@16
|
79 ++ei;
|
Chris@16
|
80 } else { // if (v_color == Color::black())
|
Chris@16
|
81 call_finish_edge(vis, *ei, g);
|
Chris@16
|
82 ++ei;
|
Chris@16
|
83 }
|
Chris@16
|
84 }
|
Chris@16
|
85 put(vertex_color, u, Color::black());
|
Chris@16
|
86 vis.finish_vertex(u, g);
|
Chris@16
|
87 if (src_e) call_finish_edge(vis, src_e.get(), g);
|
Chris@16
|
88 }
|
Chris@16
|
89 }
|
Chris@16
|
90
|
Chris@16
|
91 #else // BOOST_RECURSIVE_DFS
|
Chris@16
|
92
|
Chris@16
|
93 template <typename IncidenceGraph, typename DFSVisitor,
|
Chris@16
|
94 typename VertexColorMap, typename EdgeColorMap>
|
Chris@16
|
95 void undir_dfv_impl
|
Chris@16
|
96 (const IncidenceGraph& g,
|
Chris@16
|
97 typename graph_traits<IncidenceGraph>::vertex_descriptor u,
|
Chris@16
|
98 DFSVisitor& vis, // pass-by-reference here, important!
|
Chris@16
|
99 VertexColorMap vertex_color,
|
Chris@16
|
100 EdgeColorMap edge_color)
|
Chris@16
|
101 {
|
Chris@16
|
102 BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept<IncidenceGraph> ));
|
Chris@16
|
103 BOOST_CONCEPT_ASSERT(( DFSVisitorConcept<DFSVisitor, IncidenceGraph> ));
|
Chris@16
|
104 typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
|
Chris@16
|
105 typedef typename graph_traits<IncidenceGraph>::edge_descriptor Edge;
|
Chris@16
|
106 BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept<VertexColorMap,Vertex> ));
|
Chris@16
|
107 BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept<EdgeColorMap,Edge> ));
|
Chris@16
|
108 typedef typename property_traits<VertexColorMap>::value_type ColorValue;
|
Chris@16
|
109 typedef typename property_traits<EdgeColorMap>::value_type EColorValue;
|
Chris@16
|
110 BOOST_CONCEPT_ASSERT(( ColorValueConcept<ColorValue> ));
|
Chris@16
|
111 BOOST_CONCEPT_ASSERT(( ColorValueConcept<EColorValue> ));
|
Chris@16
|
112 typedef color_traits<ColorValue> Color;
|
Chris@16
|
113 typedef color_traits<EColorValue> EColor;
|
Chris@16
|
114 typename graph_traits<IncidenceGraph>::out_edge_iterator ei, ei_end;
|
Chris@16
|
115
|
Chris@16
|
116 put(vertex_color, u, Color::gray()); vis.discover_vertex(u, g);
|
Chris@16
|
117 for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
|
Chris@16
|
118 Vertex v = target(*ei, g); vis.examine_edge(*ei, g);
|
Chris@16
|
119 ColorValue v_color = get(vertex_color, v);
|
Chris@16
|
120 EColorValue uv_color = get(edge_color, *ei);
|
Chris@16
|
121 put(edge_color, *ei, EColor::black());
|
Chris@16
|
122 if (v_color == Color::white()) { vis.tree_edge(*ei, g);
|
Chris@16
|
123 undir_dfv_impl(g, v, vis, vertex_color, edge_color);
|
Chris@16
|
124 } else if (v_color == Color::gray() && uv_color == EColor::white())
|
Chris@16
|
125 vis.back_edge(*ei, g);
|
Chris@16
|
126 call_finish_edge(vis, *ei, g);
|
Chris@16
|
127 }
|
Chris@16
|
128 put(vertex_color, u, Color::black()); vis.finish_vertex(u, g);
|
Chris@16
|
129 }
|
Chris@16
|
130
|
Chris@16
|
131 #endif // ! BOOST_RECURSIVE_DFS
|
Chris@16
|
132
|
Chris@16
|
133 } // namespace detail
|
Chris@16
|
134
|
Chris@16
|
135 template <typename Graph, typename DFSVisitor,
|
Chris@16
|
136 typename VertexColorMap, typename EdgeColorMap,
|
Chris@16
|
137 typename Vertex>
|
Chris@16
|
138 void
|
Chris@16
|
139 undirected_dfs(const Graph& g, DFSVisitor vis,
|
Chris@16
|
140 VertexColorMap vertex_color, EdgeColorMap edge_color,
|
Chris@16
|
141 Vertex start_vertex)
|
Chris@16
|
142 {
|
Chris@16
|
143 BOOST_CONCEPT_ASSERT(( DFSVisitorConcept<DFSVisitor, Graph> ));
|
Chris@16
|
144 BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept<Graph> ));
|
Chris@16
|
145
|
Chris@16
|
146 typedef typename property_traits<VertexColorMap>::value_type ColorValue;
|
Chris@16
|
147 typedef color_traits<ColorValue> Color;
|
Chris@16
|
148
|
Chris@16
|
149 typename graph_traits<Graph>::vertex_iterator ui, ui_end;
|
Chris@16
|
150 for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
|
Chris@16
|
151 put(vertex_color, *ui, Color::white()); vis.initialize_vertex(*ui, g);
|
Chris@16
|
152 }
|
Chris@16
|
153 typename graph_traits<Graph>::edge_iterator ei, ei_end;
|
Chris@16
|
154 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
|
Chris@16
|
155 put(edge_color, *ei, Color::white());
|
Chris@16
|
156
|
Chris@16
|
157 if (start_vertex != *vertices(g).first){ vis.start_vertex(start_vertex, g);
|
Chris@16
|
158 detail::undir_dfv_impl(g, start_vertex, vis, vertex_color, edge_color);
|
Chris@16
|
159 }
|
Chris@16
|
160
|
Chris@16
|
161 for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
|
Chris@16
|
162 ColorValue u_color = get(vertex_color, *ui);
|
Chris@16
|
163 if (u_color == Color::white()) { vis.start_vertex(*ui, g);
|
Chris@16
|
164 detail::undir_dfv_impl(g, *ui, vis, vertex_color, edge_color);
|
Chris@16
|
165 }
|
Chris@16
|
166 }
|
Chris@16
|
167 }
|
Chris@16
|
168
|
Chris@16
|
169 template <typename Graph, typename DFSVisitor, typename VertexColorMap,
|
Chris@16
|
170 typename EdgeColorMap>
|
Chris@16
|
171 void
|
Chris@16
|
172 undirected_dfs(const Graph& g, DFSVisitor vis,
|
Chris@16
|
173 VertexColorMap vertex_color, EdgeColorMap edge_color)
|
Chris@16
|
174 {
|
Chris@16
|
175 undirected_dfs(g, vis, vertex_color, edge_color, *vertices(g).first);
|
Chris@16
|
176 }
|
Chris@16
|
177
|
Chris@16
|
178 namespace detail {
|
Chris@16
|
179 template <typename VertexColorMap>
|
Chris@16
|
180 struct udfs_dispatch {
|
Chris@16
|
181
|
Chris@16
|
182 template <typename Graph, typename Vertex,
|
Chris@16
|
183 typename DFSVisitor, typename EdgeColorMap,
|
Chris@16
|
184 typename P, typename T, typename R>
|
Chris@16
|
185 static void
|
Chris@16
|
186 apply(const Graph& g, DFSVisitor vis, Vertex start_vertex,
|
Chris@16
|
187 const bgl_named_params<P, T, R>&,
|
Chris@16
|
188 EdgeColorMap edge_color,
|
Chris@16
|
189 VertexColorMap vertex_color)
|
Chris@16
|
190 {
|
Chris@16
|
191 undirected_dfs(g, vis, vertex_color, edge_color, start_vertex);
|
Chris@16
|
192 }
|
Chris@16
|
193 };
|
Chris@16
|
194
|
Chris@16
|
195 template <>
|
Chris@16
|
196 struct udfs_dispatch<param_not_found> {
|
Chris@16
|
197 template <typename Graph, typename Vertex, typename DFSVisitor,
|
Chris@16
|
198 typename EdgeColorMap,
|
Chris@16
|
199 typename P, typename T, typename R>
|
Chris@16
|
200 static void
|
Chris@16
|
201 apply(const Graph& g, DFSVisitor vis, Vertex start_vertex,
|
Chris@16
|
202 const bgl_named_params<P, T, R>& params,
|
Chris@16
|
203 EdgeColorMap edge_color,
|
Chris@16
|
204 param_not_found)
|
Chris@16
|
205 {
|
Chris@16
|
206 std::vector<default_color_type> color_vec(num_vertices(g));
|
Chris@16
|
207 default_color_type c = white_color; // avoid warning about un-init
|
Chris@16
|
208 undirected_dfs
|
Chris@16
|
209 (g, vis, make_iterator_property_map
|
Chris@16
|
210 (color_vec.begin(),
|
Chris@16
|
211 choose_const_pmap(get_param(params, vertex_index),
|
Chris@16
|
212 g, vertex_index), c),
|
Chris@16
|
213 edge_color,
|
Chris@16
|
214 start_vertex);
|
Chris@16
|
215 }
|
Chris@16
|
216 };
|
Chris@16
|
217
|
Chris@16
|
218 } // namespace detail
|
Chris@16
|
219
|
Chris@16
|
220
|
Chris@16
|
221 // Named Parameter Variant
|
Chris@16
|
222 template <typename Graph, typename P, typename T, typename R>
|
Chris@16
|
223 void
|
Chris@16
|
224 undirected_dfs(const Graph& g,
|
Chris@16
|
225 const bgl_named_params<P, T, R>& params)
|
Chris@16
|
226 {
|
Chris@16
|
227 typedef typename get_param_type< vertex_color_t, bgl_named_params<P, T, R> >::type C;
|
Chris@16
|
228 detail::udfs_dispatch<C>::apply
|
Chris@16
|
229 (g,
|
Chris@16
|
230 choose_param(get_param(params, graph_visitor),
|
Chris@16
|
231 make_dfs_visitor(null_visitor())),
|
Chris@16
|
232 choose_param(get_param(params, root_vertex_t()),
|
Chris@16
|
233 *vertices(g).first),
|
Chris@16
|
234 params,
|
Chris@16
|
235 get_param(params, edge_color),
|
Chris@16
|
236 get_param(params, vertex_color)
|
Chris@16
|
237 );
|
Chris@16
|
238 }
|
Chris@16
|
239
|
Chris@16
|
240
|
Chris@16
|
241 template <typename IncidenceGraph, typename DFSVisitor,
|
Chris@16
|
242 typename VertexColorMap, typename EdgeColorMap>
|
Chris@16
|
243 void undirected_depth_first_visit
|
Chris@16
|
244 (const IncidenceGraph& g,
|
Chris@16
|
245 typename graph_traits<IncidenceGraph>::vertex_descriptor u,
|
Chris@16
|
246 DFSVisitor vis, VertexColorMap vertex_color, EdgeColorMap edge_color)
|
Chris@16
|
247 {
|
Chris@16
|
248 detail::undir_dfv_impl(g, u, vis, vertex_color, edge_color);
|
Chris@16
|
249 }
|
Chris@16
|
250
|
Chris@16
|
251
|
Chris@16
|
252 } // namespace boost
|
Chris@16
|
253
|
Chris@16
|
254
|
Chris@16
|
255 #endif
|