File indexing completed on 2025-01-18 09:37:26
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_GRAPH_DOMINATOR_HPP
0010 #define BOOST_GRAPH_DOMINATOR_HPP
0011
0012 #include <boost/config.hpp>
0013 #include <deque>
0014 #include <set>
0015 #include <boost/graph/depth_first_search.hpp>
0016 #include <boost/concept/assert.hpp>
0017
0018
0019
0020 namespace boost
0021 {
0022 namespace detail
0023 {
0024
0025
0026
0027 template < class TimeMap, class VertexVector, class TimeT, class Tag >
0028 class time_stamper_with_vertex_vector
0029 : public base_visitor<
0030 time_stamper_with_vertex_vector< TimeMap, VertexVector, TimeT, Tag > >
0031 {
0032 public:
0033 typedef Tag event_filter;
0034 time_stamper_with_vertex_vector(
0035 TimeMap timeMap, VertexVector& v, TimeT& t)
0036 : timeStamper_(timeMap, t), v_(v)
0037 {
0038 }
0039
0040 template < class Graph >
0041 void operator()(const typename property_traits< TimeMap >::key_type& v,
0042 const Graph& g)
0043 {
0044 timeStamper_(v, g);
0045 v_[timeStamper_.m_time] = v;
0046 }
0047
0048 private:
0049 time_stamper< TimeMap, TimeT, Tag > timeStamper_;
0050 VertexVector& v_;
0051 };
0052
0053
0054
0055
0056 template < class TimeMap, class VertexVector, class TimeT, class Tag >
0057 time_stamper_with_vertex_vector< TimeMap, VertexVector, TimeT, Tag >
0058 stamp_times_with_vertex_vector(
0059 TimeMap timeMap, VertexVector& v, TimeT& t, Tag)
0060 {
0061 return time_stamper_with_vertex_vector< TimeMap, VertexVector, TimeT,
0062 Tag >(timeMap, v, t);
0063 }
0064
0065 template < class Graph, class IndexMap, class TimeMap, class PredMap,
0066 class DomTreePredMap >
0067 class dominator_visitor
0068 {
0069 typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0070 typedef
0071 typename graph_traits< Graph >::vertices_size_type VerticesSizeType;
0072
0073 public:
0074
0075
0076
0077
0078
0079
0080
0081 dominator_visitor(const Graph& g, const Vertex& entry,
0082 const IndexMap& indexMap, DomTreePredMap domTreePredMap)
0083 : semi_(num_vertices(g))
0084 , ancestor_(num_vertices(g), graph_traits< Graph >::null_vertex())
0085 , samedom_(ancestor_)
0086 , best_(semi_)
0087 , semiMap_(make_iterator_property_map(semi_.begin(), indexMap))
0088 , ancestorMap_(make_iterator_property_map(ancestor_.begin(), indexMap))
0089 , bestMap_(make_iterator_property_map(best_.begin(), indexMap))
0090 , buckets_(num_vertices(g))
0091 , bucketMap_(make_iterator_property_map(buckets_.begin(), indexMap))
0092 , entry_(entry)
0093 , domTreePredMap_(domTreePredMap)
0094 , numOfVertices_(num_vertices(g))
0095 , samedomMap(make_iterator_property_map(samedom_.begin(), indexMap))
0096 {
0097 }
0098
0099 void operator()(const Vertex& n, const TimeMap& dfnumMap,
0100 const PredMap& parentMap, const Graph& g)
0101 {
0102 if (n == entry_)
0103 return;
0104
0105 const Vertex p(get(parentMap, n));
0106 Vertex s(p);
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 typename graph_traits< Graph >::in_edge_iterator inItr, inEnd;
0123 for (boost::tie(inItr, inEnd) = in_edges(n, g); inItr != inEnd;
0124 ++inItr)
0125 {
0126 const Vertex v = source(*inItr, g);
0127
0128 if (get(dfnumMap, v) < 0 || get(dfnumMap, v) >= numOfVertices_)
0129 continue;
0130
0131 Vertex s2;
0132 if (get(dfnumMap, v) <= get(dfnumMap, n))
0133 s2 = v;
0134 else
0135 s2 = get(semiMap_, ancestor_with_lowest_semi_(v, dfnumMap));
0136
0137 if (get(dfnumMap, s2) < get(dfnumMap, s))
0138 s = s2;
0139 }
0140 put(semiMap_, n, s);
0141
0142
0143
0144 get(bucketMap_, s).push_back(n);
0145 get(ancestorMap_, n) = p;
0146 get(bestMap_, n) = n;
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 typename std::deque< Vertex >::iterator buckItr;
0159 for (buckItr = get(bucketMap_, p).begin();
0160 buckItr != get(bucketMap_, p).end(); ++buckItr)
0161 {
0162 const Vertex v(*buckItr);
0163 const Vertex y(ancestor_with_lowest_semi_(v, dfnumMap));
0164 if (get(semiMap_, y) == get(semiMap_, v))
0165 put(domTreePredMap_, v, p);
0166 else
0167 put(samedomMap, v, y);
0168 }
0169
0170 get(bucketMap_, p).clear();
0171 }
0172
0173 protected:
0174
0175
0176
0177 const Vertex ancestor_with_lowest_semi_(
0178 const Vertex& v, const TimeMap& dfnumMap)
0179 {
0180 const Vertex a(get(ancestorMap_, v));
0181
0182 if (get(ancestorMap_, a) != graph_traits< Graph >::null_vertex())
0183 {
0184 const Vertex b(ancestor_with_lowest_semi_(a, dfnumMap));
0185
0186 put(ancestorMap_, v, get(ancestorMap_, a));
0187
0188 if (get(dfnumMap, get(semiMap_, b))
0189 < get(dfnumMap, get(semiMap_, get(bestMap_, v))))
0190 put(bestMap_, v, b);
0191 }
0192
0193 return get(bestMap_, v);
0194 }
0195
0196 std::vector< Vertex > semi_, ancestor_, samedom_, best_;
0197 PredMap semiMap_, ancestorMap_, bestMap_;
0198 std::vector< std::deque< Vertex > > buckets_;
0199
0200 iterator_property_map<
0201 typename std::vector< std::deque< Vertex > >::iterator, IndexMap >
0202 bucketMap_;
0203
0204 const Vertex& entry_;
0205 DomTreePredMap domTreePredMap_;
0206 const VerticesSizeType numOfVertices_;
0207
0208 public:
0209 PredMap samedomMap;
0210 };
0211
0212 }
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 template < class Graph, class IndexMap, class TimeMap, class PredMap,
0235 class VertexVector, class DomTreePredMap >
0236 void lengauer_tarjan_dominator_tree_without_dfs(const Graph& g,
0237 const typename graph_traits< Graph >::vertex_descriptor& entry,
0238 const IndexMap& indexMap, TimeMap dfnumMap, PredMap parentMap,
0239 VertexVector& verticesByDFNum, DomTreePredMap domTreePredMap)
0240 {
0241
0242 typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0243 typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType;
0244
0245 BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >));
0246
0247 const VerticesSizeType numOfVertices = num_vertices(g);
0248 if (numOfVertices == 0)
0249 return;
0250
0251
0252 detail::dominator_visitor< Graph, IndexMap, TimeMap, PredMap,
0253 DomTreePredMap >
0254 visitor(g, entry, indexMap, domTreePredMap);
0255
0256 VerticesSizeType i;
0257 for (i = 0; i < numOfVertices; ++i)
0258 {
0259 const Vertex u(verticesByDFNum[numOfVertices - 1 - i]);
0260 if (u != graph_traits< Graph >::null_vertex())
0261 visitor(u, dfnumMap, parentMap, g);
0262 }
0263
0264
0265
0266 for (i = 0; i < numOfVertices; ++i)
0267 {
0268 const Vertex n(verticesByDFNum[i]);
0269
0270 if (n == entry || n == graph_traits< Graph >::null_vertex())
0271 continue;
0272
0273 Vertex u = get(visitor.samedomMap, n);
0274 if (u != graph_traits< Graph >::null_vertex())
0275 {
0276 put(domTreePredMap, n, get(domTreePredMap, u));
0277 }
0278 }
0279 }
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289 template < class Graph, class IndexMap, class TimeMap, class PredMap,
0290 class VertexVector, class DomTreePredMap >
0291 void lengauer_tarjan_dominator_tree(const Graph& g,
0292 const typename graph_traits< Graph >::vertex_descriptor& entry,
0293 const IndexMap& indexMap, TimeMap dfnumMap, PredMap parentMap,
0294 VertexVector& verticesByDFNum, DomTreePredMap domTreePredMap)
0295 {
0296
0297 typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType;
0298
0299 BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >));
0300
0301
0302 const VerticesSizeType numOfVertices = num_vertices(g);
0303 if (numOfVertices == 0)
0304 return;
0305
0306 VerticesSizeType time = (std::numeric_limits< VerticesSizeType >::max)();
0307 std::vector< default_color_type > colors(
0308 numOfVertices, color_traits< default_color_type >::white());
0309 depth_first_visit(g, entry,
0310 make_dfs_visitor(
0311 make_pair(record_predecessors(parentMap, on_tree_edge()),
0312 detail::stamp_times_with_vertex_vector(
0313 dfnumMap, verticesByDFNum, time, on_discover_vertex()))),
0314 make_iterator_property_map(colors.begin(), indexMap));
0315
0316
0317 lengauer_tarjan_dominator_tree_without_dfs(g, entry, indexMap, dfnumMap,
0318 parentMap, verticesByDFNum, domTreePredMap);
0319 }
0320
0321
0322
0323
0324
0325
0326
0327 template < class Graph, class DomTreePredMap >
0328 void lengauer_tarjan_dominator_tree(const Graph& g,
0329 const typename graph_traits< Graph >::vertex_descriptor& entry,
0330 DomTreePredMap domTreePredMap)
0331 {
0332
0333 typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0334 typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType;
0335 typedef typename property_map< Graph, vertex_index_t >::const_type IndexMap;
0336 typedef iterator_property_map<
0337 typename std::vector< VerticesSizeType >::iterator, IndexMap >
0338 TimeMap;
0339 typedef iterator_property_map< typename std::vector< Vertex >::iterator,
0340 IndexMap >
0341 PredMap;
0342
0343
0344 const VerticesSizeType numOfVertices = num_vertices(g);
0345 if (numOfVertices == 0)
0346 return;
0347
0348 const IndexMap indexMap = get(vertex_index, g);
0349
0350 std::vector< VerticesSizeType > dfnum(numOfVertices, 0);
0351 TimeMap dfnumMap(make_iterator_property_map(dfnum.begin(), indexMap));
0352
0353 std::vector< Vertex > parent(
0354 numOfVertices, graph_traits< Graph >::null_vertex());
0355 PredMap parentMap(make_iterator_property_map(parent.begin(), indexMap));
0356
0357 std::vector< Vertex > verticesByDFNum(parent);
0358
0359
0360 lengauer_tarjan_dominator_tree(g, entry, indexMap, dfnumMap, parentMap,
0361 verticesByDFNum, domTreePredMap);
0362 }
0363
0364
0365
0366
0367
0368
0369 template < class Graph, class IndexMap, class DomTreePredMap >
0370 void iterative_bit_vector_dominator_tree(const Graph& g,
0371 const typename graph_traits< Graph >::vertex_descriptor& entry,
0372 const IndexMap& indexMap, DomTreePredMap domTreePredMap)
0373 {
0374 typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
0375 typedef typename graph_traits< Graph >::vertex_iterator vertexItr;
0376 typedef typename graph_traits< Graph >::vertices_size_type VerticesSizeType;
0377 typedef iterator_property_map<
0378 typename std::vector< std::set< Vertex > >::iterator, IndexMap >
0379 vertexSetMap;
0380
0381 BOOST_CONCEPT_ASSERT((BidirectionalGraphConcept< Graph >));
0382
0383
0384
0385 const VerticesSizeType numOfVertices = num_vertices(g);
0386 if (numOfVertices == 0)
0387 return;
0388
0389 vertexItr vi, viend;
0390 boost::tie(vi, viend) = vertices(g);
0391 const std::set< Vertex > N(vi, viend);
0392
0393 bool change = true;
0394
0395 std::vector< std::set< Vertex > > dom(numOfVertices, N);
0396 vertexSetMap domMap(make_iterator_property_map(dom.begin(), indexMap));
0397 get(domMap, entry).clear();
0398 get(domMap, entry).insert(entry);
0399
0400 while (change)
0401 {
0402 change = false;
0403 for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
0404 {
0405 if (*vi == entry)
0406 continue;
0407
0408 std::set< Vertex > T(N);
0409
0410 typename graph_traits< Graph >::in_edge_iterator inItr, inEnd;
0411 for (boost::tie(inItr, inEnd) = in_edges(*vi, g); inItr != inEnd;
0412 ++inItr)
0413 {
0414 const Vertex p = source(*inItr, g);
0415
0416 std::set< Vertex > tempSet;
0417 std::set_intersection(T.begin(), T.end(),
0418 get(domMap, p).begin(), get(domMap, p).end(),
0419 std::inserter(tempSet, tempSet.begin()));
0420 T.swap(tempSet);
0421 }
0422
0423 T.insert(*vi);
0424 if (T != get(domMap, *vi))
0425 {
0426 change = true;
0427 get(domMap, *vi).swap(T);
0428 }
0429 }
0430 }
0431
0432
0433 for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
0434 get(domMap, *vi).erase(*vi);
0435
0436 Graph domTree(numOfVertices);
0437
0438 for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
0439 {
0440 if (*vi == entry)
0441 continue;
0442
0443
0444 const std::set< Vertex > tempSet(get(domMap, *vi));
0445 typename std::set< Vertex >::const_iterator s;
0446 for (s = tempSet.begin(); s != tempSet.end(); ++s)
0447 {
0448 typename std::set< Vertex >::iterator t;
0449 for (t = get(domMap, *vi).begin(); t != get(domMap, *vi).end();)
0450 {
0451 typename std::set< Vertex >::iterator old_t = t;
0452 ++t;
0453 if (*old_t == *s)
0454 continue;
0455 if (get(domMap, *s).find(*old_t) != get(domMap, *s).end())
0456 get(domMap, *vi).erase(old_t);
0457 }
0458 }
0459 }
0460
0461 for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
0462 {
0463 if (*vi != entry && get(domMap, *vi).size() == 1)
0464 {
0465 Vertex temp = *get(domMap, *vi).begin();
0466 put(domTreePredMap, *vi, temp);
0467 }
0468 }
0469 }
0470
0471 template < class Graph, class DomTreePredMap >
0472 void iterative_bit_vector_dominator_tree(const Graph& g,
0473 const typename graph_traits< Graph >::vertex_descriptor& entry,
0474 DomTreePredMap domTreePredMap)
0475 {
0476 typename property_map< Graph, vertex_index_t >::const_type indexMap
0477 = get(vertex_index, g);
0478
0479 iterative_bit_vector_dominator_tree(g, entry, indexMap, domTreePredMap);
0480 }
0481 }
0482
0483 #endif