File indexing completed on 2025-01-18 09:37:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_GRAPH_SLOAN_HPP
0014 #define BOOST_GRAPH_SLOAN_HPP
0015
0016 #define WEIGHT1 1
0017 #define WEIGHT2 2
0018
0019 #include <boost/config.hpp>
0020 #include <vector>
0021 #include <queue>
0022 #include <algorithm>
0023 #include <limits>
0024 #include <boost/pending/queue.hpp>
0025 #include <boost/graph/graph_traits.hpp>
0026 #include <boost/graph/breadth_first_search.hpp>
0027 #include <boost/graph/properties.hpp>
0028 #include <boost/pending/indirect_cmp.hpp>
0029 #include <boost/property_map/property_map.hpp>
0030 #include <boost/graph/visitors.hpp>
0031 #include <boost/graph/adjacency_list.hpp>
0032 #include <boost/graph/cuthill_mckee_ordering.hpp>
0033
0034
0035
0036
0037
0038
0039
0040
0041 namespace boost
0042 {
0043
0044
0045
0046
0047
0048
0049 template < class Distance > typename Distance::value_type RLS_depth(Distance& d)
0050 {
0051 typename Distance::value_type h_s = 0;
0052 typename Distance::iterator iter;
0053
0054 for (iter = d.begin(); iter != d.end(); ++iter)
0055 {
0056 if (*iter > h_s)
0057 {
0058 h_s = *iter;
0059 }
0060 }
0061
0062 return h_s;
0063 }
0064
0065
0066
0067
0068
0069
0070 template < class Distance, class my_int >
0071 typename Distance::value_type RLS_max_width(Distance& d, my_int depth)
0072 {
0073
0074 typedef typename Distance::value_type Degree;
0075
0076
0077 std::vector< Degree > dummy_width(depth + 1, 0);
0078 typename std::vector< Degree >::iterator my_it;
0079 typename Distance::iterator iter;
0080 Degree w_max = 0;
0081
0082 for (iter = d.begin(); iter != d.end(); ++iter)
0083 {
0084 dummy_width[*iter]++;
0085 }
0086
0087 for (my_it = dummy_width.begin(); my_it != dummy_width.end(); ++my_it)
0088 {
0089 if (*my_it > w_max)
0090 w_max = *my_it;
0091 }
0092
0093 return w_max;
0094 }
0095
0096
0097
0098
0099
0100
0101
0102 template < class Graph, class ColorMap, class DegreeMap >
0103 typename graph_traits< Graph >::vertex_descriptor sloan_start_end_vertices(
0104 Graph& G, typename graph_traits< Graph >::vertex_descriptor& s,
0105 ColorMap color, DegreeMap degree)
0106 {
0107 typedef typename property_traits< DegreeMap >::value_type Degree;
0108 typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0109 typedef typename std::vector<
0110 typename graph_traits< Graph >::vertices_size_type >::iterator vec_iter;
0111 typedef typename graph_traits< Graph >::vertices_size_type size_type;
0112
0113 typedef typename property_map< Graph, vertex_index_t >::const_type VertexID;
0114
0115 s = *(vertices(G).first);
0116 Vertex e = s;
0117 Vertex i;
0118 Degree my_degree = get(degree, s);
0119 Degree dummy, h_i, h_s, w_i, w_e;
0120 bool new_start = true;
0121 Degree maximum_degree = 0;
0122
0123
0124
0125 std::vector< typename graph_traits< Graph >::vertices_size_type > dist(
0126 num_vertices(G), 0);
0127
0128
0129 boost::iterator_property_map< vec_iter, VertexID, size_type, size_type& >
0130 dist_pmap(dist.begin(), get(vertex_index, G));
0131
0132
0133 typename property_map< Graph, vertex_index_t >::type index_map
0134 = get(vertex_index, G);
0135
0136
0137 typedef indirect_cmp< DegreeMap, std::greater< Degree > > Compare;
0138 Compare comp(degree);
0139 std::priority_queue< Vertex, std::vector< Vertex >, Compare > degree_queue(
0140 comp);
0141
0142
0143
0144 typename graph_traits< Graph >::vertex_iterator ui, ui_end;
0145 for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
0146 {
0147 dummy = get(degree, *ui);
0148
0149 if (dummy < my_degree)
0150 {
0151 my_degree = dummy;
0152 s = *ui;
0153 }
0154
0155 if (dummy > maximum_degree)
0156 {
0157 maximum_degree = dummy;
0158 }
0159 }
0160
0161
0162 do
0163 {
0164 new_start = false;
0165
0166
0167
0168 for (typename std::vector< typename graph_traits<
0169 Graph >::vertices_size_type >::iterator iter
0170 = dist.begin();
0171 iter != dist.end(); ++iter)
0172 *iter = 0;
0173
0174
0175 breadth_first_search(G, s,
0176 visitor(
0177 make_bfs_visitor(record_distances(dist_pmap, on_tree_edge()))));
0178
0179
0180
0181
0182
0183 h_s = RLS_depth(dist);
0184
0185
0186
0187
0188 std::vector< bool > shrink_trace(maximum_degree, false);
0189 for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
0190 {
0191 dummy = get(degree, *ui);
0192
0193 if ((dist[index_map[*ui]] == h_s) && (!shrink_trace[dummy]))
0194 {
0195 degree_queue.push(*ui);
0196 shrink_trace[dummy] = true;
0197 }
0198 }
0199
0200
0201
0202
0203
0204 w_e = (std::numeric_limits< Degree >::max)();
0205
0206
0207
0208
0209 while (!degree_queue.empty())
0210 {
0211 i = degree_queue.top();
0212
0213 degree_queue.pop();
0214
0215
0216
0217 for (typename std::vector< typename graph_traits<
0218 Graph >::vertices_size_type >::iterator iter
0219 = dist.begin();
0220 iter != dist.end(); ++iter)
0221 *iter = 0;
0222
0223 breadth_first_search(G, i,
0224 boost::visitor(make_bfs_visitor(
0225 record_distances(dist_pmap, on_tree_edge()))));
0226
0227
0228 h_i = RLS_depth(dist);
0229 w_i = RLS_max_width(dist, h_i);
0230
0231
0232 if ((h_i > h_s) && (w_i < w_e))
0233 {
0234 h_s = h_i;
0235 s = i;
0236 while (!degree_queue.empty())
0237 degree_queue.pop();
0238 new_start = true;
0239 }
0240 else if (w_i < w_e)
0241 {
0242 w_e = w_i;
0243 e = i;
0244 }
0245 }
0246
0247
0248 } while (new_start);
0249
0250 return e;
0251 }
0252
0253
0254
0255
0256
0257
0258
0259 template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
0260 class PriorityMap, class Weight >
0261 OutputIterator sloan_ordering(Graph& g,
0262 typename graph_traits< Graph >::vertex_descriptor s,
0263 typename graph_traits< Graph >::vertex_descriptor e,
0264 OutputIterator permutation, ColorMap color, DegreeMap degree,
0265 PriorityMap priority, Weight W1, Weight W2)
0266 {
0267
0268 typedef typename property_traits< PriorityMap >::value_type Degree;
0269 typedef typename property_traits< ColorMap >::value_type ColorValue;
0270 typedef color_traits< ColorValue > Color;
0271 typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0272 typedef typename std::vector<
0273 typename graph_traits< Graph >::vertices_size_type >::iterator vec_iter;
0274 typedef typename graph_traits< Graph >::vertices_size_type size_type;
0275
0276 typedef typename property_map< Graph, vertex_index_t >::const_type VertexID;
0277
0278
0279 typename std::vector< typename graph_traits< Graph >::vertices_size_type >
0280 dist(num_vertices(g), 0);
0281
0282
0283 boost::iterator_property_map< vec_iter, VertexID, size_type, size_type& >
0284 dist_pmap(dist.begin(), get(vertex_index, g));
0285
0286 breadth_first_search(g, e,
0287 visitor(make_bfs_visitor(record_distances(dist_pmap, on_tree_edge()))));
0288
0289
0290 typename property_map< Graph, vertex_index_t >::type index_map
0291 = get(vertex_index, g);
0292
0293
0294 Degree cdeg;
0295 typename graph_traits< Graph >::vertex_iterator ui, ui_end;
0296 for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
0297 {
0298 put(color, *ui, Color::white());
0299 cdeg = get(degree, *ui) + 1;
0300 put(priority, *ui, W1 * dist[index_map[*ui]] - W2 * cdeg);
0301 }
0302
0303
0304 typedef indirect_cmp< PriorityMap, std::greater< Degree > > Compare;
0305 Compare comp(priority);
0306 std::list< Vertex > priority_list;
0307
0308
0309 typename graph_traits< Graph >::out_edge_iterator ei, ei_end, ei2, ei2_end;
0310 Vertex u, v, w;
0311
0312 put(color, s,
0313 Color::green());
0314 priority_list.push_front(s);
0315
0316 while (!priority_list.empty())
0317 {
0318 priority_list.sort(comp);
0319
0320
0321 u = priority_list
0322 .front();
0323 priority_list
0324 .pop_front();
0325
0326 if (get(color, u) == Color::green())
0327 {
0328
0329 for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
0330 {
0331 v = target(*ei, g);
0332
0333 put(priority, v, get(priority, v) + W2);
0334
0335 if (get(color, v)
0336 == Color::white())
0337 {
0338 put(color, v,
0339 Color::green());
0340 priority_list.push_front(
0341 v);
0342 }
0343 }
0344 }
0345
0346
0347 *permutation++
0348 = u;
0349 put(color, u, Color::black());
0350
0351
0352 for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
0353 {
0354
0355 v = target(*ei, g);
0356
0357 if (get(color, v) == Color::green())
0358 {
0359
0360 put(color, v,
0361 Color::red());
0362 put(priority, v, get(priority, v) + W2);
0363
0364
0365 for (boost::tie(ei2, ei2_end) = out_edges(v, g); ei2 != ei2_end;
0366 ++ei2)
0367 {
0368 w = target(*ei2, g);
0369
0370 if (get(color, w) != Color::black())
0371 {
0372
0373 put(priority, w,
0374 get(priority, w) + W2);
0375
0376 if (get(color, w) == Color::white())
0377 {
0378
0379 put(color, w, Color::green());
0380
0381 priority_list.push_front(
0382 w);
0383
0384 }
0385
0386 }
0387
0388 }
0389
0390 }
0391
0392 }
0393
0394 }
0395
0396 return permutation;
0397 }
0398
0399
0400
0401
0402 template < class Graph, class OutputIterator, class ColorMap, class DegreeMap,
0403 class PriorityMap >
0404 OutputIterator sloan_ordering(Graph& g,
0405 typename graph_traits< Graph >::vertex_descriptor s,
0406 typename graph_traits< Graph >::vertex_descriptor e,
0407 OutputIterator permutation, ColorMap color, DegreeMap degree,
0408 PriorityMap priority)
0409 {
0410 return sloan_ordering(
0411 g, s, e, permutation, color, degree, priority, WEIGHT1, WEIGHT2);
0412 }
0413
0414
0415
0416
0417
0418
0419
0420
0421 template < class Graph, class OutputIterator, class Color, class Degree,
0422 class Priority, class Weight >
0423 inline OutputIterator sloan_ordering(Graph& G, OutputIterator permutation,
0424 Color color, Degree degree, Priority priority, Weight W1, Weight W2)
0425 {
0426 typedef typename boost::graph_traits< Graph >::vertex_descriptor Vertex;
0427
0428 Vertex s, e;
0429 e = sloan_start_end_vertices(G, s, color, degree);
0430
0431 return sloan_ordering(
0432 G, s, e, permutation, color, degree, priority, W1, W2);
0433 }
0434
0435
0436
0437 template < class Graph, class OutputIterator, class Color, class Degree,
0438 class Priority >
0439 inline OutputIterator sloan_ordering(Graph& G, OutputIterator permutation,
0440 Color color, Degree degree, Priority priority)
0441 {
0442 return sloan_ordering(
0443 G, permutation, color, degree, priority, WEIGHT1, WEIGHT2);
0444 }
0445
0446 }
0447
0448 #endif