00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef UTILMM_GRAPH_UNDIRECTED_DFS_HPP
00015 #define UTILMM_GRAPH_UNDIRECTED_DFS_HPP
00016
00017 #include <boost/graph/depth_first_search.hpp>
00018 #include <vector>
00019
00020 namespace utilmm {
00021 namespace detail {
00022 using namespace boost;
00023 struct nontruth2 {
00024 template<class T, class T2>
00025 bool operator()(const T&, const T2&) const { return false; }
00026 };
00027
00028 template <typename IncidenceGraph, typename DFSVisitor,
00029 typename VertexColorMap, typename EdgeColorMap,
00030 typename TerminatorFunc>
00031 void undir_dfv_impl_term
00032 (const IncidenceGraph& g,
00033 typename graph_traits<IncidenceGraph>::vertex_descriptor u,
00034 DFSVisitor& vis,
00035 VertexColorMap vertex_color,
00036 EdgeColorMap edge_color,
00037 TerminatorFunc func = TerminatorFunc())
00038 {
00039 function_requires<IncidenceGraphConcept<IncidenceGraph> >();
00040 function_requires<DFSVisitorConcept<DFSVisitor, IncidenceGraph> >();
00041 typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
00042 typedef typename graph_traits<IncidenceGraph>::edge_descriptor Edge;
00043 function_requires<ReadWritePropertyMapConcept<VertexColorMap,Vertex> >();
00044 function_requires<ReadWritePropertyMapConcept<EdgeColorMap,Edge> >();
00045 typedef typename property_traits<VertexColorMap>::value_type ColorValue;
00046 typedef typename property_traits<EdgeColorMap>::value_type EColorValue;
00047 function_requires< ColorValueConcept<ColorValue> >();
00048 function_requires< ColorValueConcept<EColorValue> >();
00049 typedef color_traits<ColorValue> Color;
00050 typedef color_traits<EColorValue> EColor;
00051 typedef typename graph_traits<IncidenceGraph>::out_edge_iterator Iter;
00052 typedef std::pair<Vertex, std::pair<Iter, Iter> > VertexInfo;
00053
00054 std::vector<VertexInfo> stack;
00055
00056 put(vertex_color, u, Color::gray());
00057 vis.discover_vertex(u, g);
00058
00059 Iter ei, ei_end;
00060 tie(ei, ei_end) = out_edges(u, g);
00061 if (func(u, g))
00062 stack.push_back(std::make_pair(u, std::make_pair(ei_end, ei_end)));
00063 else
00064 stack.push_back(std::make_pair(u, std::make_pair(ei, ei_end)));
00065
00066 while (!stack.empty()) {
00067 VertexInfo& back = stack.back();
00068 u = back.first;
00069 tie(ei, ei_end) = back.second;
00070 stack.pop_back();
00071 while (ei != ei_end) {
00072 Vertex v = target(*ei, g);
00073 vis.examine_edge(*ei, g);
00074 ColorValue v_color = get(vertex_color, v);
00075 EColorValue uv_color = get(edge_color, *ei);
00076 put(edge_color, *ei, EColor::black());
00077 if (v_color == Color::white()) {
00078 vis.tree_edge(*ei, g);
00079 stack.push_back(std::make_pair(u, std::make_pair(++ei, ei_end)));
00080 u = v;
00081 put(vertex_color, u, Color::gray());
00082 vis.discover_vertex(u, g);
00083 tie(ei, ei_end) = out_edges(u, g);
00084 if (func(u, g))
00085 ei = ei_end;
00086 } else if (v_color == Color::gray()) {
00087 if (uv_color == EColor::white()) vis.back_edge(*ei, g);
00088 ++ei;
00089 } else {
00090 vis.forward_or_cross_edge(*ei, g);
00091 ++ei;
00092 }
00093 }
00094 put(vertex_color, u, Color::black());
00095 vis.finish_vertex(u, g);
00096 }
00097 }
00098 }
00099
00100 template <typename Graph, typename DFSVisitor,
00101 typename VertexColorMap, typename EdgeColorMap,
00102 typename Vertex>
00103 void
00104 undirected_dfs(const Graph& g, DFSVisitor vis,
00105 VertexColorMap vertex_color, EdgeColorMap edge_color,
00106 Vertex start_vertex)
00107 {
00108 using namespace boost;
00109 function_requires<DFSVisitorConcept<DFSVisitor, Graph> >();
00110 function_requires<EdgeListGraphConcept<Graph> >();
00111
00112 typedef typename property_traits<VertexColorMap>::value_type ColorValue;
00113 typedef color_traits<ColorValue> Color;
00114
00115 typename graph_traits<Graph>::vertex_iterator ui, ui_end;
00116 for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
00117 put(vertex_color, *ui, Color::white()); vis.initialize_vertex(*ui, g);
00118 }
00119 typename graph_traits<Graph>::edge_iterator ei, ei_end;
00120 for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
00121 put(edge_color, *ei, Color::white());
00122
00123 if (start_vertex != *vertices(g).first){ vis.start_vertex(start_vertex, g);
00124 detail::undir_dfv_impl_term(g, start_vertex, vis, vertex_color, edge_color, detail::nontruth2());
00125 }
00126
00127 for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
00128 ColorValue u_color = get(vertex_color, *ui);
00129 if (u_color == Color::white()) { vis.start_vertex(*ui, g);
00130 detail::undir_dfv_impl_term(g, *ui, vis, vertex_color, edge_color, detail::nontruth2());
00131 }
00132 }
00133 }
00134
00135 template <typename Graph, typename DFSVisitor, typename VertexColorMap,
00136 typename EdgeColorMap>
00137 void
00138 undirected_dfs(const Graph& g, DFSVisitor vis,
00139 VertexColorMap vertex_color, EdgeColorMap edge_color)
00140 {
00141 using namespace boost;
00142 undirected_dfs(g, vis, vertex_color, edge_color, *vertices(g).first, detail::nontruth2());
00143 }
00144
00145 namespace detail {
00146 template <typename VertexColorMap>
00147 struct udfs_dispatch {
00148
00149 template <typename Graph, typename Vertex,
00150 typename DFSVisitor, typename EdgeColorMap,
00151 typename P, typename T, typename R>
00152 static void
00153 apply(const Graph& g, DFSVisitor vis, Vertex start_vertex,
00154 const bgl_named_params<P, T, R>&,
00155 EdgeColorMap edge_color,
00156 VertexColorMap vertex_color)
00157 {
00158 undirected_dfs(g, vis, vertex_color, edge_color, start_vertex);
00159 }
00160 };
00161
00162 template <>
00163 struct udfs_dispatch<boost::detail::error_property_not_found> {
00164 template <typename Graph, typename Vertex, typename DFSVisitor,
00165 typename EdgeColorMap,
00166 typename P, typename T, typename R>
00167 static void
00168 apply(const Graph& g, DFSVisitor vis, Vertex start_vertex,
00169 const bgl_named_params<P, T, R>& params,
00170 EdgeColorMap edge_color,
00171 boost::detail::error_property_not_found)
00172 {
00173 std::vector<default_color_type> color_vec(num_vertices(g));
00174 default_color_type c = white_color;
00175 undirected_dfs
00176 (g, vis, make_iterator_property_map
00177 (color_vec.begin(),
00178 choose_const_pmap(get_param(params, vertex_index),
00179 g, vertex_index), c),
00180 edge_color,
00181 start_vertex);
00182 }
00183 };
00184
00185 }
00186
00187
00188
00189 template <typename Graph, typename P, typename T, typename R>
00190 void
00191 undirected_dfs(const Graph& g,
00192 const boost::bgl_named_params<P, T, R>& params)
00193 {
00194 using namespace boost;
00195 typedef typename property_value< bgl_named_params<P, T, R>,
00196 vertex_color_t>::type C;
00197 detail::udfs_dispatch<C>::apply
00198 (g,
00199 choose_param(get_param(params, graph_visitor),
00200 make_dfs_visitor(null_visitor())),
00201 choose_param(get_param(params, root_vertex_t()),
00202 *vertices(g).first),
00203 params,
00204 get_param(params, edge_color),
00205 get_param(params, vertex_color)
00206 );
00207 }
00208
00209
00210 template <typename IncidenceGraph, typename DFSVisitor,
00211 typename VertexColorMap, typename EdgeColorMap,
00212 typename TerminatorFunc>
00213 void undirected_depth_first_visit
00214 (const IncidenceGraph& g,
00215 typename boost::graph_traits<IncidenceGraph>::vertex_descriptor u,
00216 DFSVisitor vis, VertexColorMap vertex_color, EdgeColorMap edge_color,
00217 TerminatorFunc func = TerminatorFunc())
00218 {
00219 detail::undir_dfv_impl_term(g, u, vis, vertex_color, edge_color, func);
00220 }
00221
00222
00223 }
00224
00225
00226 #endif