annotate DEPENDENCIES/generic/include/boost/graph/two_graphs_common_spanning_trees.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright (C) 2012, Michele Caini.
Chris@16 2 // Distributed under the Boost Software License, Version 1.0.
Chris@16 3 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 4 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 // Two Graphs Common Spanning Trees Algorithm
Chris@16 7 // Based on academic article of Mint, Read and Tarjan
Chris@16 8 // Efficient Algorithm for Common Spanning Tree Problem
Chris@16 9 // Electron. Lett., 28 April 1983, Volume 19, Issue 9, p.346-347
Chris@16 10
Chris@16 11
Chris@16 12 #ifndef BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP
Chris@16 13 #define BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP
Chris@16 14
Chris@16 15
Chris@16 16 #include <boost/config.hpp>
Chris@16 17
Chris@16 18 #include <boost/bimap.hpp>
Chris@16 19 #include <boost/type_traits.hpp>
Chris@16 20 #include <boost/concept/requires.hpp>
Chris@16 21 #include <boost/graph/graph_traits.hpp>
Chris@16 22 #include <boost/graph/undirected_dfs.hpp>
Chris@16 23 #include <boost/graph/connected_components.hpp>
Chris@16 24 #include <boost/graph/filtered_graph.hpp>
Chris@16 25 #include <vector>
Chris@16 26 #include <stack>
Chris@16 27 #include <map>
Chris@16 28
Chris@16 29
Chris@16 30 namespace boost
Chris@16 31 {
Chris@16 32
Chris@16 33
Chris@16 34 namespace detail {
Chris@16 35
Chris@16 36
Chris@16 37 template
Chris@16 38 <
Chris@16 39 typename TreeMap,
Chris@16 40 typename PredMap,
Chris@16 41 typename DistMap,
Chris@16 42 typename LowMap,
Chris@16 43 typename Buffer
Chris@16 44 >
Chris@16 45 struct bridges_visitor: public default_dfs_visitor
Chris@16 46 {
Chris@16 47 bridges_visitor(
Chris@16 48 TreeMap tree,
Chris@16 49 PredMap pred,
Chris@16 50 DistMap dist,
Chris@16 51 LowMap low,
Chris@16 52 Buffer& buffer
Chris@16 53 ): mTree(tree), mPred(pred), mDist(dist), mLow(low), mBuffer(buffer)
Chris@16 54 { mNum = -1; }
Chris@16 55
Chris@16 56 template <typename Vertex, typename Graph>
Chris@16 57 void initialize_vertex(const Vertex& u, const Graph& g)
Chris@16 58 {
Chris@16 59 put(mPred, u, u);
Chris@16 60 put(mDist, u, -1);
Chris@16 61 }
Chris@16 62
Chris@16 63 template <typename Vertex, typename Graph>
Chris@16 64 void discover_vertex(const Vertex& u, const Graph& g)
Chris@16 65 {
Chris@16 66 put(mDist, u, ++mNum);
Chris@16 67 put(mLow, u, get(mDist, u));
Chris@16 68 }
Chris@16 69
Chris@16 70 template <typename Edge, typename Graph>
Chris@16 71 void tree_edge(const Edge& e, const Graph& g)
Chris@16 72 {
Chris@16 73 put(mPred, target(e, g), source(e, g));
Chris@16 74 put(mTree, target(e, g), e);
Chris@16 75 }
Chris@16 76
Chris@16 77 template <typename Edge, typename Graph>
Chris@16 78 void back_edge(const Edge& e, const Graph& g)
Chris@16 79 {
Chris@16 80 put(mLow, source(e, g),
Chris@16 81 (std::min)(get(mLow, source(e, g)), get(mDist, target(e, g))));
Chris@16 82 }
Chris@16 83
Chris@16 84 template <typename Vertex, typename Graph>
Chris@16 85 void finish_vertex(const Vertex& u, const Graph& g)
Chris@16 86 {
Chris@16 87 Vertex parent = get(mPred, u);
Chris@16 88 if(get(mLow, u) > get(mDist, parent))
Chris@16 89 mBuffer.push(get(mTree, u));
Chris@16 90 put(mLow, parent,
Chris@16 91 (std::min)(get(mLow, parent), get(mLow, u)));
Chris@16 92 }
Chris@16 93
Chris@16 94 TreeMap mTree;
Chris@16 95 PredMap mPred;
Chris@16 96 DistMap mDist;
Chris@16 97 LowMap mLow;
Chris@16 98 Buffer& mBuffer;
Chris@16 99 int mNum;
Chris@16 100 };
Chris@16 101
Chris@16 102
Chris@16 103 template <typename Buffer>
Chris@16 104 struct cycle_finder: public base_visitor< cycle_finder<Buffer> >
Chris@16 105 {
Chris@16 106 typedef on_back_edge event_filter;
Chris@16 107 cycle_finder(): mBuffer(0) { }
Chris@16 108 cycle_finder(Buffer* buffer)
Chris@16 109 : mBuffer(buffer) { }
Chris@16 110 template <typename Edge, typename Graph>
Chris@16 111 void operator()(const Edge& e, const Graph& g)
Chris@16 112 {
Chris@16 113 if(mBuffer)
Chris@16 114 mBuffer->push(e);
Chris@16 115 }
Chris@16 116 Buffer* mBuffer;
Chris@16 117 };
Chris@16 118
Chris@16 119
Chris@16 120 template <typename DeletedMap>
Chris@16 121 struct deleted_edge_status
Chris@16 122 {
Chris@16 123 deleted_edge_status() { }
Chris@16 124 deleted_edge_status(DeletedMap map): mMap(map) { }
Chris@16 125 template <typename Edge>
Chris@16 126 bool operator()(const Edge& e) const
Chris@16 127 { return (!get(mMap, e)); }
Chris@16 128 DeletedMap mMap;
Chris@16 129 };
Chris@16 130
Chris@16 131
Chris@16 132 template <typename InLMap>
Chris@16 133 struct inL_edge_status
Chris@16 134 {
Chris@16 135 inL_edge_status() { }
Chris@16 136 inL_edge_status(InLMap map): mMap(map) { }
Chris@16 137 template <typename Edge>
Chris@16 138 bool operator()(const Edge& e) const
Chris@16 139 { return get(mMap, e); }
Chris@16 140 InLMap mMap;
Chris@16 141 };
Chris@16 142
Chris@16 143
Chris@16 144 template <
Chris@16 145 typename Graph,
Chris@16 146 typename Func,
Chris@16 147 typename Seq,
Chris@16 148 typename Map
Chris@16 149 >
Chris@16 150 void rec_two_graphs_common_spanning_trees
Chris@16 151 (
Chris@16 152 const Graph& iG,
Chris@16 153 bimap<
Chris@16 154 bimaps::set_of<int>,
Chris@16 155 bimaps::set_of< typename graph_traits<Graph>::edge_descriptor >
Chris@16 156 > iG_bimap,
Chris@16 157 Map aiG_inL,
Chris@16 158 Map diG,
Chris@16 159 const Graph& vG,
Chris@16 160 bimap<
Chris@16 161 bimaps::set_of<int>,
Chris@16 162 bimaps::set_of< typename graph_traits<Graph>::edge_descriptor >
Chris@16 163 > vG_bimap,
Chris@16 164 Map avG_inL,
Chris@16 165 Map dvG,
Chris@16 166 Func func,
Chris@16 167 Seq inL
Chris@16 168 )
Chris@16 169 {
Chris@16 170 typedef graph_traits<Graph> GraphTraits;
Chris@16 171
Chris@16 172 typedef typename GraphTraits::vertex_descriptor vertex_descriptor;
Chris@16 173 typedef typename GraphTraits::edge_descriptor edge_descriptor;
Chris@16 174
Chris@16 175 typedef typename Seq::size_type seq_size_type;
Chris@16 176
Chris@16 177 int edges = num_vertices(iG) - 1;
Chris@16 178 //
Chris@16 179 // [ Michele Caini ]
Chris@16 180 //
Chris@16 181 // Using the condition (edges != 0) leads to the accidental submission of
Chris@16 182 // sub-graphs ((V-1+1)-fake-tree, named here fat-tree).
Chris@16 183 // Remove this condition is a workaround for the problem of fat-trees.
Chris@16 184 // Please do not add that condition, even if it improves performance.
Chris@16 185 //
Chris@16 186 // Here is proposed the previous guard (that was wrong):
Chris@16 187 // for(seq_size_type i = 0; (i < inL.size()) && (edges != 0); ++i)
Chris@16 188 //
Chris@16 189 {
Chris@16 190 for(seq_size_type i = 0; i < inL.size(); ++i)
Chris@16 191 if(inL[i])
Chris@16 192 --edges;
Chris@16 193
Chris@16 194 if(edges < 0)
Chris@16 195 return;
Chris@16 196 }
Chris@16 197
Chris@16 198 bool is_tree = (edges == 0);
Chris@16 199 if(is_tree) {
Chris@16 200 func(inL);
Chris@16 201 } else {
Chris@16 202 std::map<vertex_descriptor, default_color_type> vertex_color;
Chris@16 203 std::map<edge_descriptor, default_color_type> edge_color;
Chris@16 204
Chris@16 205 std::stack<edge_descriptor> iG_buf, vG_buf;
Chris@16 206 bool found = false;
Chris@16 207
Chris@16 208 seq_size_type m;
Chris@16 209 for(seq_size_type j = 0; j < inL.size() && !found; ++j) {
Chris@16 210 if(!inL[j]
Chris@16 211 && !get(diG, iG_bimap.left.at(j))
Chris@16 212 && !get(dvG, vG_bimap.left.at(j)))
Chris@16 213 {
Chris@16 214 put(aiG_inL, iG_bimap.left.at(j), true);
Chris@16 215 put(avG_inL, vG_bimap.left.at(j), true);
Chris@16 216
Chris@16 217 undirected_dfs(
Chris@16 218 make_filtered_graph(iG,
Chris@16 219 detail::inL_edge_status< associative_property_map<
Chris@16 220 std::map<edge_descriptor, bool> > >(aiG_inL)),
Chris@16 221 make_dfs_visitor(
Chris@16 222 detail::cycle_finder< std::stack<edge_descriptor> > (&iG_buf)),
Chris@16 223 associative_property_map<
Chris@16 224 std::map<vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 225 associative_property_map<
Chris@16 226 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 227 );
Chris@16 228 undirected_dfs(
Chris@16 229 make_filtered_graph(vG,
Chris@16 230 detail::inL_edge_status< associative_property_map<
Chris@16 231 std::map<edge_descriptor, bool> > >(avG_inL)),
Chris@16 232 make_dfs_visitor(
Chris@16 233 detail::cycle_finder< std::stack<edge_descriptor> > (&vG_buf)),
Chris@16 234 associative_property_map<
Chris@16 235 std::map<vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 236 associative_property_map<
Chris@16 237 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 238 );
Chris@16 239
Chris@16 240 if(iG_buf.empty() && vG_buf.empty()) {
Chris@16 241 inL[j] = true;
Chris@16 242 found = true;
Chris@16 243 m = j;
Chris@16 244 } else {
Chris@16 245 while(!iG_buf.empty()) iG_buf.pop();
Chris@16 246 while(!vG_buf.empty()) vG_buf.pop();
Chris@16 247 put(aiG_inL, iG_bimap.left.at(j), false);
Chris@16 248 put(avG_inL, vG_bimap.left.at(j), false);
Chris@16 249 }
Chris@16 250 }
Chris@16 251 }
Chris@16 252
Chris@16 253 if(found) {
Chris@16 254
Chris@16 255 std::stack<edge_descriptor> iG_buf_copy, vG_buf_copy;
Chris@16 256 for(seq_size_type j = 0; j < inL.size(); ++j) {
Chris@16 257 if(!inL[j]
Chris@16 258 && !get(diG, iG_bimap.left.at(j))
Chris@16 259 && !get(dvG, vG_bimap.left.at(j)))
Chris@16 260 {
Chris@16 261
Chris@16 262 put(aiG_inL, iG_bimap.left.at(j), true);
Chris@16 263 put(avG_inL, vG_bimap.left.at(j), true);
Chris@16 264
Chris@16 265 undirected_dfs(
Chris@16 266 make_filtered_graph(iG,
Chris@16 267 detail::inL_edge_status< associative_property_map<
Chris@16 268 std::map<edge_descriptor, bool> > >(aiG_inL)),
Chris@16 269 make_dfs_visitor(
Chris@16 270 detail::cycle_finder<
Chris@16 271 std::stack<edge_descriptor> > (&iG_buf)),
Chris@16 272 associative_property_map< std::map<
Chris@16 273 vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 274 associative_property_map<
Chris@16 275 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 276 );
Chris@16 277 undirected_dfs(
Chris@16 278 make_filtered_graph(vG,
Chris@16 279 detail::inL_edge_status< associative_property_map<
Chris@16 280 std::map<edge_descriptor, bool> > >(avG_inL)),
Chris@16 281 make_dfs_visitor(
Chris@16 282 detail::cycle_finder<
Chris@16 283 std::stack<edge_descriptor> > (&vG_buf)),
Chris@16 284 associative_property_map< std::map<
Chris@16 285 vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 286 associative_property_map<
Chris@16 287 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 288 );
Chris@16 289
Chris@16 290 if(!iG_buf.empty() || !vG_buf.empty()) {
Chris@16 291 while(!iG_buf.empty()) iG_buf.pop();
Chris@16 292 while(!vG_buf.empty()) vG_buf.pop();
Chris@16 293 put(diG, iG_bimap.left.at(j), true);
Chris@16 294 put(dvG, vG_bimap.left.at(j), true);
Chris@16 295 iG_buf_copy.push(iG_bimap.left.at(j));
Chris@16 296 vG_buf_copy.push(vG_bimap.left.at(j));
Chris@16 297 }
Chris@16 298
Chris@16 299 put(aiG_inL, iG_bimap.left.at(j), false);
Chris@16 300 put(avG_inL, vG_bimap.left.at(j), false);
Chris@16 301 }
Chris@16 302 }
Chris@16 303
Chris@16 304 // REC
Chris@16 305 detail::rec_two_graphs_common_spanning_trees<Graph, Func, Seq, Map>
Chris@16 306 (iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL, dvG, func, inL);
Chris@16 307
Chris@16 308 while(!iG_buf_copy.empty()) {
Chris@16 309 put(diG, iG_buf_copy.top(), false);
Chris@16 310 put(dvG, vG_bimap.left.at(
Chris@16 311 iG_bimap.right.at(iG_buf_copy.top())), false);
Chris@16 312 iG_buf_copy.pop();
Chris@16 313 }
Chris@16 314 while(!vG_buf_copy.empty()) {
Chris@16 315 put(dvG, vG_buf_copy.top(), false);
Chris@16 316 put(diG, iG_bimap.left.at(
Chris@16 317 vG_bimap.right.at(vG_buf_copy.top())), false);
Chris@16 318 vG_buf_copy.pop();
Chris@16 319 }
Chris@16 320
Chris@16 321 inL[m] = false;
Chris@16 322 put(aiG_inL, iG_bimap.left.at(m), false);
Chris@16 323 put(avG_inL, vG_bimap.left.at(m), false);
Chris@16 324
Chris@16 325 put(diG, iG_bimap.left.at(m), true);
Chris@16 326 put(dvG, vG_bimap.left.at(m), true);
Chris@16 327
Chris@16 328 std::map<vertex_descriptor, edge_descriptor> tree_map;
Chris@16 329 std::map<vertex_descriptor, vertex_descriptor> pred_map;
Chris@16 330 std::map<vertex_descriptor, int> dist_map, low_map;
Chris@16 331
Chris@16 332 detail::bridges_visitor<
Chris@16 333 associative_property_map<
Chris@16 334 std::map<vertex_descriptor, edge_descriptor>
Chris@16 335 >,
Chris@16 336 associative_property_map<
Chris@16 337 std::map<vertex_descriptor, vertex_descriptor>
Chris@16 338 >,
Chris@16 339 associative_property_map< std::map<vertex_descriptor, int> >,
Chris@16 340 associative_property_map< std::map<vertex_descriptor, int> >,
Chris@16 341 std::stack<edge_descriptor>
Chris@16 342 >
Chris@16 343 iG_vis(
Chris@16 344 associative_property_map<
Chris@16 345 std::map< vertex_descriptor, edge_descriptor> >(tree_map),
Chris@16 346 associative_property_map<
Chris@16 347 std::map< vertex_descriptor, vertex_descriptor> >(pred_map),
Chris@16 348 associative_property_map<
Chris@16 349 std::map< vertex_descriptor, int> >(dist_map),
Chris@16 350 associative_property_map<
Chris@16 351 std::map< vertex_descriptor, int> >(low_map),
Chris@16 352 iG_buf
Chris@16 353 ),
Chris@16 354 vG_vis(
Chris@16 355 associative_property_map<
Chris@16 356 std::map< vertex_descriptor, edge_descriptor> >(tree_map),
Chris@16 357 associative_property_map<
Chris@16 358 std::map< vertex_descriptor, vertex_descriptor> >(pred_map),
Chris@16 359 associative_property_map<
Chris@16 360 std::map< vertex_descriptor, int> >(dist_map),
Chris@16 361 associative_property_map<
Chris@16 362 std::map< vertex_descriptor, int> >(low_map),
Chris@16 363 vG_buf
Chris@16 364 );
Chris@16 365
Chris@16 366 undirected_dfs(make_filtered_graph(iG,
Chris@16 367 detail::deleted_edge_status< associative_property_map<
Chris@16 368 std::map<edge_descriptor, bool> > >(diG)),
Chris@16 369 iG_vis,
Chris@16 370 associative_property_map<
Chris@16 371 std::map<vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 372 associative_property_map<
Chris@16 373 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 374 );
Chris@16 375 undirected_dfs(make_filtered_graph(vG,
Chris@16 376 detail::deleted_edge_status< associative_property_map<
Chris@16 377 std::map<edge_descriptor, bool> > >(dvG)),
Chris@16 378 vG_vis,
Chris@16 379 associative_property_map<
Chris@16 380 std::map<vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 381 associative_property_map<
Chris@16 382 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 383 );
Chris@16 384
Chris@16 385 found = false;
Chris@16 386 std::stack<edge_descriptor> iG_buf_tmp, vG_buf_tmp;
Chris@16 387 while(!iG_buf.empty() && !found) {
Chris@16 388 if(!inL[iG_bimap.right.at(iG_buf.top())]) {
Chris@16 389 put(aiG_inL, iG_buf.top(), true);
Chris@16 390 put(avG_inL, vG_bimap.left.at(
Chris@16 391 iG_bimap.right.at(iG_buf.top())), true);
Chris@16 392
Chris@16 393 undirected_dfs(
Chris@16 394 make_filtered_graph(iG,
Chris@16 395 detail::inL_edge_status< associative_property_map<
Chris@16 396 std::map<edge_descriptor, bool> > >(aiG_inL)),
Chris@16 397 make_dfs_visitor(
Chris@16 398 detail::cycle_finder<
Chris@16 399 std::stack<edge_descriptor> > (&iG_buf_tmp)),
Chris@16 400 associative_property_map<
Chris@16 401 std::map<
Chris@16 402 vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 403 associative_property_map<
Chris@16 404 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 405 );
Chris@16 406 undirected_dfs(
Chris@16 407 make_filtered_graph(vG,
Chris@16 408 detail::inL_edge_status< associative_property_map<
Chris@16 409 std::map<edge_descriptor, bool> > >(avG_inL)),
Chris@16 410 make_dfs_visitor(
Chris@16 411 detail::cycle_finder<
Chris@16 412 std::stack<edge_descriptor> > (&vG_buf_tmp)),
Chris@16 413 associative_property_map<
Chris@16 414 std::map<
Chris@16 415 vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 416 associative_property_map<
Chris@16 417 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 418 );
Chris@16 419
Chris@16 420 if(!iG_buf_tmp.empty() || !vG_buf_tmp.empty()) {
Chris@16 421 found = true;
Chris@16 422 } else {
Chris@16 423 while(!iG_buf_tmp.empty()) iG_buf_tmp.pop();
Chris@16 424 while(!vG_buf_tmp.empty()) vG_buf_tmp.pop();
Chris@16 425 iG_buf_copy.push(iG_buf.top());
Chris@16 426 }
Chris@16 427
Chris@16 428 put(aiG_inL, iG_buf.top(), false);
Chris@16 429 put(avG_inL, vG_bimap.left.at(
Chris@16 430 iG_bimap.right.at(iG_buf.top())), false);
Chris@16 431 }
Chris@16 432 iG_buf.pop();
Chris@16 433 }
Chris@16 434 while(!vG_buf.empty() && !found) {
Chris@16 435 if(!inL[vG_bimap.right.at(vG_buf.top())]) {
Chris@16 436 put(avG_inL, vG_buf.top(), true);
Chris@16 437 put(aiG_inL, iG_bimap.left.at(
Chris@16 438 vG_bimap.right.at(vG_buf.top())), true);
Chris@16 439
Chris@16 440 undirected_dfs(
Chris@16 441 make_filtered_graph(iG,
Chris@16 442 detail::inL_edge_status< associative_property_map<
Chris@16 443 std::map<edge_descriptor, bool> > >(aiG_inL)),
Chris@16 444 make_dfs_visitor(
Chris@16 445 detail::cycle_finder<
Chris@16 446 std::stack<edge_descriptor> > (&iG_buf_tmp)),
Chris@16 447 associative_property_map<
Chris@16 448 std::map<
Chris@16 449 vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 450 associative_property_map<
Chris@16 451 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 452 );
Chris@16 453 undirected_dfs(
Chris@16 454 make_filtered_graph(vG,
Chris@16 455 detail::inL_edge_status< associative_property_map<
Chris@16 456 std::map<edge_descriptor, bool> > >(avG_inL)),
Chris@16 457 make_dfs_visitor(
Chris@16 458 detail::cycle_finder<
Chris@16 459 std::stack<edge_descriptor> > (&vG_buf_tmp)),
Chris@16 460 associative_property_map<
Chris@16 461 std::map<
Chris@16 462 vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 463 associative_property_map<
Chris@16 464 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 465 );
Chris@16 466
Chris@16 467 if(!iG_buf_tmp.empty() || !vG_buf_tmp.empty()) {
Chris@16 468 found = true;
Chris@16 469 } else {
Chris@16 470 while(!iG_buf_tmp.empty()) iG_buf_tmp.pop();
Chris@16 471 while(!vG_buf_tmp.empty()) vG_buf_tmp.pop();
Chris@16 472 vG_buf_copy.push(vG_buf.top());
Chris@16 473 }
Chris@16 474
Chris@16 475 put(avG_inL, vG_buf.top(), false);
Chris@16 476 put(aiG_inL, iG_bimap.left.at(
Chris@16 477 vG_bimap.right.at(vG_buf.top())), false);
Chris@16 478 }
Chris@16 479 vG_buf.pop();
Chris@16 480 }
Chris@16 481
Chris@16 482 if(!found) {
Chris@16 483
Chris@16 484 while(!iG_buf_copy.empty()) {
Chris@16 485 inL[iG_bimap.right.at(iG_buf_copy.top())] = true;
Chris@16 486 put(aiG_inL, iG_buf_copy.top(), true);
Chris@16 487 put(avG_inL, vG_bimap.left.at(
Chris@16 488 iG_bimap.right.at(iG_buf_copy.top())), true);
Chris@16 489 iG_buf.push(iG_buf_copy.top());
Chris@16 490 iG_buf_copy.pop();
Chris@16 491 }
Chris@16 492 while(!vG_buf_copy.empty()) {
Chris@16 493 inL[vG_bimap.right.at(vG_buf_copy.top())] = true;
Chris@16 494 put(avG_inL, vG_buf_copy.top(), true);
Chris@16 495 put(aiG_inL, iG_bimap.left.at(
Chris@16 496 vG_bimap.right.at(vG_buf_copy.top())), true);
Chris@16 497 vG_buf.push(vG_buf_copy.top());
Chris@16 498 vG_buf_copy.pop();
Chris@16 499 }
Chris@16 500
Chris@16 501 // REC
Chris@16 502 detail::rec_two_graphs_common_spanning_trees<
Chris@16 503 Graph, Func, Seq, Map>
Chris@16 504 (iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL, dvG, func, inL);
Chris@16 505
Chris@16 506 while(!iG_buf.empty()) {
Chris@16 507 inL[iG_bimap.right.at(iG_buf.top())] = false;
Chris@16 508 put(aiG_inL, iG_buf.top(), false);
Chris@16 509 put(avG_inL, vG_bimap.left.at(
Chris@16 510 iG_bimap.right.at(iG_buf.top())), false);
Chris@16 511 iG_buf.pop();
Chris@16 512 }
Chris@16 513 while(!vG_buf.empty()) {
Chris@16 514 inL[vG_bimap.right.at(vG_buf.top())] = false;
Chris@16 515 put(avG_inL, vG_buf.top(), false);
Chris@16 516 put(aiG_inL, iG_bimap.left.at(
Chris@16 517 vG_bimap.right.at(vG_buf.top())), false);
Chris@16 518 vG_buf.pop();
Chris@16 519 }
Chris@16 520
Chris@16 521 }
Chris@16 522
Chris@16 523 put(diG, iG_bimap.left.at(m), false);
Chris@16 524 put(dvG, vG_bimap.left.at(m), false);
Chris@16 525
Chris@16 526 }
Chris@16 527 }
Chris@16 528 }
Chris@16 529
Chris@16 530 } // namespace detail
Chris@16 531
Chris@16 532
Chris@16 533
Chris@16 534 template <typename Coll, typename Seq>
Chris@16 535 struct tree_collector
Chris@16 536 {
Chris@16 537
Chris@16 538 public:
Chris@16 539 BOOST_CONCEPT_ASSERT((BackInsertionSequence<Coll>));
Chris@16 540 BOOST_CONCEPT_ASSERT((RandomAccessContainer<Seq>));
Chris@16 541 BOOST_CONCEPT_ASSERT((CopyConstructible<Seq>));
Chris@16 542
Chris@16 543 typedef typename Coll::value_type coll_value_type;
Chris@16 544 typedef typename Seq::value_type seq_value_type;
Chris@16 545
Chris@16 546 BOOST_STATIC_ASSERT((is_same<coll_value_type, Seq>::value));
Chris@16 547 BOOST_STATIC_ASSERT((is_same<seq_value_type, bool>::value));
Chris@16 548
Chris@16 549 tree_collector(Coll& seqs): mSeqs(seqs) { }
Chris@16 550
Chris@16 551 inline void operator()(Seq seq)
Chris@16 552 { mSeqs.push_back(seq); }
Chris@16 553
Chris@16 554 private:
Chris@16 555 Coll& mSeqs;
Chris@16 556
Chris@16 557 };
Chris@16 558
Chris@16 559
Chris@16 560
Chris@16 561 template <
Chris@16 562 typename Graph,
Chris@16 563 typename Order,
Chris@16 564 typename Func,
Chris@16 565 typename Seq
Chris@16 566 >
Chris@16 567 BOOST_CONCEPT_REQUIRES(
Chris@16 568 ((RandomAccessContainer<Order>))
Chris@16 569 ((IncidenceGraphConcept<Graph>))
Chris@16 570 ((UnaryFunction<Func, void, Seq>))
Chris@16 571 ((Mutable_RandomAccessContainer<Seq>))
Chris@16 572 ((VertexAndEdgeListGraphConcept<Graph>)),
Chris@16 573 (void)
Chris@16 574 )
Chris@16 575 two_graphs_common_spanning_trees
Chris@16 576 (
Chris@16 577 const Graph& iG,
Chris@16 578 Order iG_map,
Chris@16 579 const Graph& vG,
Chris@16 580 Order vG_map,
Chris@16 581 Func func,
Chris@16 582 Seq inL
Chris@16 583 )
Chris@16 584 {
Chris@16 585 typedef graph_traits<Graph> GraphTraits;
Chris@16 586
Chris@16 587 typedef typename GraphTraits::directed_category directed_category;
Chris@16 588 typedef typename GraphTraits::vertex_descriptor vertex_descriptor;
Chris@16 589 typedef typename GraphTraits::edge_descriptor edge_descriptor;
Chris@16 590
Chris@16 591 typedef typename GraphTraits::edges_size_type edges_size_type;
Chris@16 592 typedef typename GraphTraits::edge_iterator edge_iterator;
Chris@16 593
Chris@16 594 typedef typename Seq::value_type seq_value_type;
Chris@16 595 typedef typename Seq::size_type seq_size_type;
Chris@16 596
Chris@16 597 typedef typename Order::value_type order_value_type;
Chris@16 598 typedef typename Order::size_type order_size_type;
Chris@16 599
Chris@16 600 BOOST_STATIC_ASSERT((is_same<order_value_type, edge_descriptor>::value));
Chris@16 601 BOOST_CONCEPT_ASSERT((Convertible<order_size_type, edges_size_type>));
Chris@16 602
Chris@16 603 BOOST_CONCEPT_ASSERT((Convertible<seq_size_type, edges_size_type>));
Chris@16 604 BOOST_STATIC_ASSERT((is_same<seq_value_type, bool>::value));
Chris@16 605
Chris@16 606 BOOST_STATIC_ASSERT((is_same<directed_category, undirected_tag>::value));
Chris@16 607
Chris@16 608 if(num_vertices(iG) != num_vertices(vG))
Chris@16 609 return;
Chris@16 610
Chris@16 611 if(inL.size() != num_edges(iG)
Chris@16 612 || inL.size() != num_edges(vG))
Chris@16 613 return;
Chris@16 614
Chris@16 615 if(iG_map.size() != num_edges(iG)
Chris@16 616 || vG_map.size() != num_edges(vG))
Chris@16 617 return;
Chris@16 618
Chris@16 619 typedef bimaps::bimap<
Chris@16 620 bimaps::set_of< int >,
Chris@16 621 bimaps::set_of< order_value_type >
Chris@16 622 > bimap_type;
Chris@16 623 typedef typename bimap_type::value_type bimap_value;
Chris@16 624
Chris@16 625 bimap_type iG_bimap, vG_bimap;
Chris@16 626 for(order_size_type i = 0; i < iG_map.size(); ++i)
Chris@16 627 iG_bimap.insert(bimap_value(i, iG_map[i]));
Chris@16 628 for(order_size_type i = 0; i < vG_map.size(); ++i)
Chris@16 629 vG_bimap.insert(bimap_value(i, vG_map[i]));
Chris@16 630
Chris@16 631 edge_iterator current, last;
Chris@16 632 boost::tuples::tie(current, last) = edges(iG);
Chris@16 633 for(; current != last; ++current)
Chris@16 634 if(iG_bimap.right.find(*current) == iG_bimap.right.end())
Chris@16 635 return;
Chris@16 636 boost::tuples::tie(current, last) = edges(vG);
Chris@16 637 for(; current != last; ++current)
Chris@16 638 if(vG_bimap.right.find(*current) == vG_bimap.right.end())
Chris@16 639 return;
Chris@16 640
Chris@16 641 std::stack<edge_descriptor> iG_buf, vG_buf;
Chris@16 642
Chris@16 643 std::map<vertex_descriptor, edge_descriptor> tree_map;
Chris@16 644 std::map<vertex_descriptor, vertex_descriptor> pred_map;
Chris@16 645 std::map<vertex_descriptor, int> dist_map, low_map;
Chris@16 646
Chris@16 647 detail::bridges_visitor<
Chris@16 648 associative_property_map<
Chris@16 649 std::map<vertex_descriptor, edge_descriptor>
Chris@16 650 >,
Chris@16 651 associative_property_map<
Chris@16 652 std::map<vertex_descriptor, vertex_descriptor>
Chris@16 653 >,
Chris@16 654 associative_property_map< std::map<vertex_descriptor, int> >,
Chris@16 655 associative_property_map< std::map<vertex_descriptor, int> >,
Chris@16 656 std::stack<edge_descriptor>
Chris@16 657 >
Chris@16 658 iG_vis(
Chris@16 659 associative_property_map<
Chris@16 660 std::map< vertex_descriptor, edge_descriptor> >(tree_map),
Chris@16 661 associative_property_map<
Chris@16 662 std::map< vertex_descriptor, vertex_descriptor> >(pred_map),
Chris@16 663 associative_property_map<std::map< vertex_descriptor, int> >(dist_map),
Chris@16 664 associative_property_map<std::map< vertex_descriptor, int> >(low_map),
Chris@16 665 iG_buf
Chris@16 666 ),
Chris@16 667 vG_vis(
Chris@16 668 associative_property_map<
Chris@16 669 std::map< vertex_descriptor, edge_descriptor> >(tree_map),
Chris@16 670 associative_property_map<
Chris@16 671 std::map< vertex_descriptor, vertex_descriptor> >(pred_map),
Chris@16 672 associative_property_map<std::map< vertex_descriptor, int> >(dist_map),
Chris@16 673 associative_property_map<std::map< vertex_descriptor, int> >(low_map),
Chris@16 674 vG_buf
Chris@16 675 );
Chris@16 676
Chris@16 677 std::map<vertex_descriptor, default_color_type> vertex_color;
Chris@16 678 std::map<edge_descriptor, default_color_type> edge_color;
Chris@16 679
Chris@16 680 undirected_dfs(iG, iG_vis,
Chris@16 681 associative_property_map<
Chris@16 682 std::map<vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 683 associative_property_map<
Chris@16 684 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 685 );
Chris@16 686 undirected_dfs(vG, vG_vis,
Chris@16 687 associative_property_map<
Chris@16 688 std::map<vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 689 associative_property_map<
Chris@16 690 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 691 );
Chris@16 692
Chris@16 693 while(!iG_buf.empty()) {
Chris@16 694 inL[iG_bimap.right.at(iG_buf.top())] = true;
Chris@16 695 iG_buf.pop();
Chris@16 696 }
Chris@16 697 while(!vG_buf.empty()) {
Chris@16 698 inL[vG_bimap.right.at(vG_buf.top())] = true;
Chris@16 699 vG_buf.pop();
Chris@16 700 }
Chris@16 701
Chris@16 702 std::map<edge_descriptor, bool> iG_inL, vG_inL;
Chris@16 703 associative_property_map< std::map<edge_descriptor, bool> >
Chris@16 704 aiG_inL(iG_inL), avG_inL(vG_inL);
Chris@16 705
Chris@16 706 for(seq_size_type i = 0; i < inL.size(); ++i)
Chris@16 707 {
Chris@16 708 if(inL[i]) {
Chris@16 709 put(aiG_inL, iG_bimap.left.at(i), true);
Chris@16 710 put(avG_inL, vG_bimap.left.at(i), true);
Chris@16 711 } else {
Chris@16 712 put(aiG_inL, iG_bimap.left.at(i), false);
Chris@16 713 put(avG_inL, vG_bimap.left.at(i), false);
Chris@16 714 }
Chris@16 715 }
Chris@16 716
Chris@16 717 undirected_dfs(
Chris@16 718 make_filtered_graph(iG,
Chris@16 719 detail::inL_edge_status< associative_property_map<
Chris@16 720 std::map<edge_descriptor, bool> > >(aiG_inL)),
Chris@16 721 make_dfs_visitor(
Chris@16 722 detail::cycle_finder< std::stack<edge_descriptor> > (&iG_buf)),
Chris@16 723 associative_property_map<
Chris@16 724 std::map<vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 725 associative_property_map<
Chris@16 726 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 727 );
Chris@16 728 undirected_dfs(
Chris@16 729 make_filtered_graph(vG,
Chris@16 730 detail::inL_edge_status< associative_property_map<
Chris@16 731 std::map<edge_descriptor, bool> > >(avG_inL)),
Chris@16 732 make_dfs_visitor(
Chris@16 733 detail::cycle_finder< std::stack<edge_descriptor> > (&vG_buf)),
Chris@16 734 associative_property_map<
Chris@16 735 std::map<vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 736 associative_property_map<
Chris@16 737 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 738 );
Chris@16 739
Chris@16 740 if(iG_buf.empty() && vG_buf.empty()) {
Chris@16 741
Chris@16 742 std::map<edge_descriptor, bool> iG_deleted, vG_deleted;
Chris@16 743 associative_property_map< std::map<edge_descriptor, bool> > diG(iG_deleted);
Chris@16 744 associative_property_map< std::map<edge_descriptor, bool> > dvG(vG_deleted);
Chris@16 745
Chris@16 746 boost::tuples::tie(current, last) = edges(iG);
Chris@16 747 for(; current != last; ++current)
Chris@16 748 put(diG, *current, false);
Chris@16 749 boost::tuples::tie(current, last) = edges(vG);
Chris@16 750 for(; current != last; ++current)
Chris@16 751 put(dvG, *current, false);
Chris@16 752
Chris@16 753 for(seq_size_type j = 0; j < inL.size(); ++j) {
Chris@16 754 if(!inL[j]) {
Chris@16 755 put(aiG_inL, iG_bimap.left.at(j), true);
Chris@16 756 put(avG_inL, vG_bimap.left.at(j), true);
Chris@16 757
Chris@16 758 undirected_dfs(
Chris@16 759 make_filtered_graph(iG,
Chris@16 760 detail::inL_edge_status< associative_property_map<
Chris@16 761 std::map<edge_descriptor, bool> > >(aiG_inL)),
Chris@16 762 make_dfs_visitor(
Chris@16 763 detail::cycle_finder< std::stack<edge_descriptor> > (&iG_buf)),
Chris@16 764 associative_property_map<
Chris@16 765 std::map<vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 766 associative_property_map<
Chris@16 767 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 768 );
Chris@16 769 undirected_dfs(
Chris@16 770 make_filtered_graph(vG,
Chris@16 771 detail::inL_edge_status< associative_property_map<
Chris@16 772 std::map<edge_descriptor, bool> > >(avG_inL)),
Chris@16 773 make_dfs_visitor(
Chris@16 774 detail::cycle_finder< std::stack<edge_descriptor> > (&vG_buf)),
Chris@16 775 associative_property_map<
Chris@16 776 std::map<vertex_descriptor, default_color_type> >(vertex_color),
Chris@16 777 associative_property_map<
Chris@16 778 std::map<edge_descriptor, default_color_type> >(edge_color)
Chris@16 779 );
Chris@16 780
Chris@16 781 if(!iG_buf.empty() || !vG_buf.empty()) {
Chris@16 782 while(!iG_buf.empty()) iG_buf.pop();
Chris@16 783 while(!vG_buf.empty()) vG_buf.pop();
Chris@16 784 put(diG, iG_bimap.left.at(j), true);
Chris@16 785 put(dvG, vG_bimap.left.at(j), true);
Chris@16 786 }
Chris@16 787
Chris@16 788 put(aiG_inL, iG_bimap.left.at(j), false);
Chris@16 789 put(avG_inL, vG_bimap.left.at(j), false);
Chris@16 790 }
Chris@16 791 }
Chris@16 792
Chris@16 793 int cc = 0;
Chris@16 794
Chris@16 795 std::map<vertex_descriptor, int> com_map;
Chris@16 796 cc += connected_components(
Chris@16 797 make_filtered_graph(iG,
Chris@16 798 detail::deleted_edge_status<associative_property_map<
Chris@16 799 std::map<edge_descriptor, bool> > >(diG)),
Chris@16 800 associative_property_map<std::map<vertex_descriptor, int> >(com_map)
Chris@16 801 );
Chris@16 802 cc += connected_components(
Chris@16 803 make_filtered_graph(vG,
Chris@16 804 detail::deleted_edge_status<associative_property_map<
Chris@16 805 std::map<edge_descriptor, bool> > >(dvG)),
Chris@16 806 associative_property_map< std::map<vertex_descriptor, int> >(com_map)
Chris@16 807 );
Chris@16 808
Chris@16 809 if(cc != 2)
Chris@16 810 return;
Chris@16 811
Chris@16 812 // REC
Chris@16 813 detail::rec_two_graphs_common_spanning_trees<Graph, Func, Seq,
Chris@16 814 associative_property_map< std::map<edge_descriptor, bool> > >
Chris@16 815 (iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL, dvG, func, inL);
Chris@16 816
Chris@16 817 }
Chris@16 818
Chris@16 819 }
Chris@16 820
Chris@16 821
Chris@16 822 template <
Chris@16 823 typename Graph,
Chris@16 824 typename Func,
Chris@16 825 typename Seq
Chris@16 826 >
Chris@16 827 BOOST_CONCEPT_REQUIRES(
Chris@16 828 ((IncidenceGraphConcept<Graph>))
Chris@16 829 ((EdgeListGraphConcept<Graph>)),
Chris@16 830 (void)
Chris@16 831 )
Chris@16 832 two_graphs_common_spanning_trees
Chris@16 833 (
Chris@16 834 const Graph& iG,
Chris@16 835 const Graph& vG,
Chris@16 836 Func func,
Chris@16 837 Seq inL
Chris@16 838 )
Chris@16 839 {
Chris@16 840 typedef graph_traits<Graph> GraphTraits;
Chris@16 841
Chris@16 842 typedef typename GraphTraits::edge_descriptor edge_descriptor;
Chris@16 843 typedef typename GraphTraits::edge_iterator edge_iterator;
Chris@16 844
Chris@16 845 std::vector<edge_descriptor> iGO, vGO;
Chris@16 846 edge_iterator curr, last;
Chris@16 847
Chris@16 848 boost::tuples::tie(curr, last) = edges(iG);
Chris@16 849 for(; curr != last; ++curr)
Chris@16 850 iGO.push_back(*curr);
Chris@16 851
Chris@16 852 boost::tuples::tie(curr, last) = edges(vG);
Chris@16 853 for(; curr != last; ++curr)
Chris@16 854 vGO.push_back(*curr);
Chris@16 855
Chris@16 856 two_graphs_common_spanning_trees(iG, iGO, vG, vGO, func, inL);
Chris@16 857 }
Chris@16 858
Chris@16 859
Chris@16 860 } // namespace boost
Chris@16 861
Chris@16 862
Chris@16 863 #endif // BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP