File indexing completed on 2025-01-18 09:37:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_GRAPH_KING_HPP
0012 #define BOOST_GRAPH_KING_HPP
0013
0014 #include <deque>
0015 #include <vector>
0016 #include <algorithm>
0017 #include <boost/config.hpp>
0018 #include <boost/bind/bind.hpp>
0019 #include <boost/tuple/tuple.hpp>
0020 #include <boost/graph/detail/sparse_ordering.hpp>
0021 #include <boost/graph/graph_utility.hpp>
0022
0023
0024
0025
0026
0027 namespace boost
0028 {
0029 namespace detail
0030 {
0031 template < typename OutputIterator, typename Buffer, typename Compare,
0032 typename PseudoDegreeMap, typename VecMap, typename VertexIndexMap >
0033 class bfs_king_visitor : public default_bfs_visitor
0034 {
0035 public:
0036 bfs_king_visitor(OutputIterator* iter, Buffer* b, Compare compare,
0037 PseudoDegreeMap deg, std::vector< int > loc, VecMap color,
0038 VertexIndexMap vertices)
0039 : permutation(iter)
0040 , Qptr(b)
0041 , degree(deg)
0042 , comp(compare)
0043 , Qlocation(loc)
0044 , colors(color)
0045 , vertex_map(vertices)
0046 {
0047 }
0048
0049 template < typename Vertex, typename Graph >
0050 void finish_vertex(Vertex, Graph& g)
0051 {
0052 using namespace boost::placeholders;
0053
0054 typename graph_traits< Graph >::out_edge_iterator ei, ei_end;
0055 Vertex v, w;
0056
0057 typedef typename std::deque< Vertex >::reverse_iterator
0058 reverse_iterator;
0059
0060 reverse_iterator rend = Qptr->rend() - index_begin;
0061 reverse_iterator rbegin = Qptr->rbegin();
0062
0063
0064 std::make_heap(rbegin, rend, boost::bind< bool >(comp, _2, _1));
0065
0066 unsigned i = 0;
0067
0068 for (i = index_begin; i != Qptr->size(); ++i)
0069 {
0070 colors[get(vertex_map, (*Qptr)[i])] = 1;
0071 Qlocation[get(vertex_map, (*Qptr)[i])] = i;
0072 }
0073
0074 i = 0;
0075
0076 for (; rbegin != rend; rend--)
0077 {
0078 percolate_down< Vertex >(i);
0079 w = (*Qptr)[index_begin + i];
0080 for (boost::tie(ei, ei_end) = out_edges(w, g); ei != ei_end;
0081 ++ei)
0082 {
0083 v = target(*ei, g);
0084 put(degree, v, get(degree, v) - 1);
0085
0086 if (colors[get(vertex_map, v)] == 1)
0087 {
0088 percolate_up< Vertex >(get(vertex_map, v), i);
0089 }
0090 }
0091
0092 colors[get(vertex_map, w)] = 0;
0093 i++;
0094 }
0095 }
0096
0097 template < typename Vertex, typename Graph >
0098 void examine_vertex(Vertex u, const Graph&)
0099 {
0100
0101 *(*permutation)++ = u;
0102 index_begin = Qptr->size();
0103 }
0104
0105 protected:
0106
0107 template < typename Vertex > void percolate_down(int offset)
0108 {
0109 int heap_last = index_begin + offset;
0110 int heap_first = Qptr->size() - 1;
0111
0112
0113
0114 std::swap((*Qptr)[heap_last], (*Qptr)[heap_first]);
0115
0116
0117 std::swap(Qlocation[heap_first], Qlocation[heap_last]);
0118
0119
0120 int drifter = heap_first;
0121 int drifter_heap = Qptr->size() - drifter;
0122
0123 int right_child_heap = drifter_heap * 2 + 1;
0124 int right_child = Qptr->size() - right_child_heap;
0125
0126 int left_child_heap = drifter_heap * 2;
0127 int left_child = Qptr->size() - left_child_heap;
0128
0129
0130 bool valid = (right_child < heap_last) ? false : true;
0131
0132
0133
0134 int smallest_child = (valid
0135 && get(degree, (*Qptr)[left_child])
0136 > get(degree, (*Qptr)[right_child]))
0137 ? right_child
0138 : left_child;
0139
0140 while (valid && smallest_child < heap_last
0141 && comp((*Qptr)[drifter], (*Qptr)[smallest_child]))
0142 {
0143
0144
0145 std::swap((*Qptr)[smallest_child], (*Qptr)[drifter]);
0146 std::swap(Qlocation[drifter], Qlocation[smallest_child]);
0147
0148
0149 drifter = smallest_child;
0150 drifter_heap = Qptr->size() - drifter;
0151
0152 right_child_heap = drifter_heap * 2 + 1;
0153 right_child = Qptr->size() - right_child_heap;
0154
0155 left_child_heap = drifter_heap * 2;
0156 left_child = Qptr->size() - left_child_heap;
0157
0158 valid = (right_child < heap_last) ? false : true;
0159
0160 smallest_child = (valid
0161 && get(degree, (*Qptr)[left_child])
0162 > get(degree, (*Qptr)[right_child]))
0163 ? right_child
0164 : left_child;
0165 }
0166 }
0167
0168
0169
0170 template < typename Vertex > void percolate_up(int vertex, int offset)
0171 {
0172
0173 int child_location = Qlocation[vertex];
0174 int heap_child_location = Qptr->size() - child_location;
0175 int heap_parent_location = (int)(heap_child_location / 2);
0176 unsigned parent_location = Qptr->size() - heap_parent_location;
0177
0178 bool valid = (heap_parent_location != 0
0179 && child_location > index_begin + offset
0180 && parent_location < Qptr->size());
0181
0182 while (valid
0183 && comp((*Qptr)[child_location], (*Qptr)[parent_location]))
0184 {
0185
0186
0187 std::swap((*Qptr)[child_location], (*Qptr)[parent_location]);
0188
0189
0190 std::swap(
0191 Qlocation[child_location], Qlocation[parent_location]);
0192
0193 child_location = parent_location;
0194 heap_child_location = heap_parent_location;
0195 heap_parent_location = (int)(heap_child_location / 2);
0196 parent_location = Qptr->size() - heap_parent_location;
0197 valid = (heap_parent_location != 0
0198 && child_location > index_begin + offset);
0199 }
0200 }
0201
0202 OutputIterator* permutation;
0203 int index_begin;
0204 Buffer* Qptr;
0205 PseudoDegreeMap degree;
0206 Compare comp;
0207 std::vector< int > Qlocation;
0208 VecMap colors;
0209 VertexIndexMap vertex_map;
0210 };
0211
0212 }
0213
0214 template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
0215 typename VertexIndexMap >
0216 OutputIterator king_ordering(const Graph& g,
0217 std::deque< typename graph_traits< Graph >::vertex_descriptor >
0218 vertex_queue,
0219 OutputIterator permutation, ColorMap color, DegreeMap degree,
0220 VertexIndexMap index_map)
0221 {
0222 typedef typename property_traits< DegreeMap >::value_type ds_type;
0223 typedef typename property_traits< ColorMap >::value_type ColorValue;
0224 typedef color_traits< ColorValue > Color;
0225 typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0226 typedef iterator_property_map< typename std::vector< ds_type >::iterator,
0227 VertexIndexMap, ds_type, ds_type& >
0228 PseudoDegreeMap;
0229 typedef indirect_cmp< PseudoDegreeMap, std::less< ds_type > > Compare;
0230 typedef typename boost::sparse::sparse_ordering_queue< Vertex > queue;
0231 typedef typename detail::bfs_king_visitor< OutputIterator, queue, Compare,
0232 PseudoDegreeMap, std::vector< int >, VertexIndexMap >
0233 Visitor;
0234 typedef
0235 typename graph_traits< Graph >::vertices_size_type vertices_size_type;
0236 std::vector< ds_type > pseudo_degree_vec(num_vertices(g));
0237 PseudoDegreeMap pseudo_degree(pseudo_degree_vec.begin(), index_map);
0238
0239 typename graph_traits< Graph >::vertex_iterator ui, ui_end;
0240 queue Q;
0241
0242
0243 for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
0244 {
0245 put(pseudo_degree, *ui, get(degree, *ui));
0246 put(color, *ui, Color::white());
0247 }
0248
0249 Compare comp(pseudo_degree);
0250 std::vector< int > colors(num_vertices(g));
0251
0252 for (vertices_size_type i = 0; i < num_vertices(g); i++)
0253 colors[i] = 0;
0254
0255 std::vector< int > loc(num_vertices(g));
0256
0257
0258 Visitor vis(&permutation, &Q, comp, pseudo_degree, loc, colors, index_map);
0259
0260 while (!vertex_queue.empty())
0261 {
0262 Vertex s = vertex_queue.front();
0263 vertex_queue.pop_front();
0264
0265
0266 breadth_first_visit(g, s, Q, vis, color);
0267 }
0268
0269 return permutation;
0270 }
0271
0272
0273 template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
0274 typename VertexIndexMap >
0275 OutputIterator king_ordering(const Graph& g,
0276 typename graph_traits< Graph >::vertex_descriptor s,
0277 OutputIterator permutation, ColorMap color, DegreeMap degree,
0278 VertexIndexMap index_map)
0279 {
0280
0281 std::deque< typename graph_traits< Graph >::vertex_descriptor >
0282 vertex_queue;
0283 vertex_queue.push_front(s);
0284 return king_ordering(
0285 g, vertex_queue, permutation, color, degree, index_map);
0286 }
0287
0288 template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
0289 class VertexIndexMap >
0290 OutputIterator king_ordering(const Graph& G, OutputIterator permutation,
0291 ColorMap color, DegreeMap degree, VertexIndexMap index_map)
0292 {
0293 if (has_no_vertices(G))
0294 return permutation;
0295
0296 typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex;
0297 typedef typename property_traits< ColorMap >::value_type ColorValue;
0298 typedef color_traits< ColorValue > Color;
0299
0300 std::deque< Vertex > vertex_queue;
0301
0302
0303 BGL_FORALL_VERTICES_T(v, G, Graph) put(color, v, Color::white());
0304
0305
0306 BGL_FORALL_VERTICES_T(v, G, Graph)
0307 {
0308 if (get(color, v) == Color::white())
0309 {
0310 depth_first_visit(G, v, dfs_visitor<>(), color);
0311 vertex_queue.push_back(v);
0312 }
0313 }
0314
0315
0316
0317 for (typename std::deque< Vertex >::iterator i = vertex_queue.begin();
0318 i != vertex_queue.end(); ++i)
0319 *i = find_starting_node(G, *i, color, degree);
0320
0321 return king_ordering(
0322 G, vertex_queue, permutation, color, degree, index_map);
0323 }
0324
0325 template < typename Graph, typename OutputIterator, typename VertexIndexMap >
0326 OutputIterator king_ordering(
0327 const Graph& G, OutputIterator permutation, VertexIndexMap index_map)
0328 {
0329 if (has_no_vertices(G))
0330 return permutation;
0331
0332 std::vector< default_color_type > colors(num_vertices(G));
0333 return king_ordering(G, permutation,
0334 make_iterator_property_map(&colors[0], index_map, colors[0]),
0335 make_out_degree_map(G), index_map);
0336 }
0337
0338 template < typename Graph, typename OutputIterator >
0339 inline OutputIterator king_ordering(const Graph& G, OutputIterator permutation)
0340 {
0341 return king_ordering(G, permutation, get(vertex_index, G));
0342 }
0343
0344 }
0345
0346 #endif