diff --git a/CMakeLists.txt b/CMakeLists.txt index 94b15f0bf..c2ebd1066 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,6 @@ target_link_libraries(boost_graph Boost::any Boost::array Boost::assert - Boost::bimap Boost::concept_check Boost::config Boost::container_hash diff --git a/build.jam b/build.jam index fa2b2e5f1..3a9172027 100644 --- a/build.jam +++ b/build.jam @@ -10,7 +10,6 @@ constant boost_dependencies : /boost/any//boost_any /boost/array//boost_array /boost/assert//boost_assert - /boost/bimap//boost_bimap /boost/concept_check//boost_concept_check /boost/config//boost_config /boost/container_hash//boost_container_hash diff --git a/include/boost/graph/two_graphs_common_spanning_trees.hpp b/include/boost/graph/two_graphs_common_spanning_trees.hpp index a41dc84b2..1b5a3d7cc 100644 --- a/include/boost/graph/two_graphs_common_spanning_trees.hpp +++ b/include/boost/graph/two_graphs_common_spanning_trees.hpp @@ -13,7 +13,6 @@ #include -#include #include #include #include @@ -23,6 +22,8 @@ #include #include #include +#include +#include namespace boost { @@ -123,14 +124,44 @@ namespace detail InLMap mMap; }; + // Position/edge lookup used by the algorithm below. left maps a position + // index to its edge, right maps an edge back to its position. + template < typename Edge > struct index_bimap + { + using value_type = std::pair< std::size_t, Edge >; + + struct left_type + { + std::vector< Edge > store; + // i is a dense position in [0, n), so unchecked access is safe. + const Edge& operator[](std::size_t i) const { return store[i]; } + } left; + + struct right_type + { + using map_type = std::map< Edge, std::size_t >; + using const_iterator = typename map_type::const_iterator; + map_type store; + std::size_t at(const Edge& e) const { return store.at(e); } + const_iterator find(const Edge& e) const { return store.find(e); } + const_iterator end() const { return store.end(); } + } right; + + void insert(const value_type& v) + { + if (left.store.size() <= v.first) + left.store.resize(v.first + 1); + left.store[v.first] = v.second; + right.store[v.second] = v.first; + } + }; + template < typename Graph, typename Func, typename Seq, typename Map > void rec_two_graphs_common_spanning_trees(const Graph& iG, - bimap< bimaps::set_of< int >, - bimaps::set_of< typename graph_traits< Graph >::edge_descriptor > > + index_bimap< typename graph_traits< Graph >::edge_descriptor > iG_bimap, Map aiG_inL, Map diG, const Graph& vG, - bimap< bimaps::set_of< int >, - bimaps::set_of< typename graph_traits< Graph >::edge_descriptor > > + index_bimap< typename graph_traits< Graph >::edge_descriptor > vG_bimap, Map avG_inL, Map dvG, Func func, Seq inL) { @@ -179,11 +210,11 @@ namespace detail seq_size_type m; for (seq_size_type j = 0; j < inL.size() && !found; ++j) { - if (!inL[j] && !get(diG, iG_bimap.left.at(j)) - && !get(dvG, vG_bimap.left.at(j))) + if (!inL[j] && !get(diG, iG_bimap.left[j]) + && !get(dvG, vG_bimap.left[j])) { - put(aiG_inL, iG_bimap.left.at(j), true); - put(avG_inL, vG_bimap.left.at(j), true); + put(aiG_inL, iG_bimap.left[j], true); + put(avG_inL, vG_bimap.left[j], true); undirected_dfs( make_filtered_graph(iG, @@ -222,8 +253,8 @@ namespace detail iG_buf.pop(); while (!vG_buf.empty()) vG_buf.pop(); - put(aiG_inL, iG_bimap.left.at(j), false); - put(avG_inL, vG_bimap.left.at(j), false); + put(aiG_inL, iG_bimap.left[j], false); + put(avG_inL, vG_bimap.left[j], false); } } } @@ -234,12 +265,12 @@ namespace detail std::stack< edge_descriptor > iG_buf_copy, vG_buf_copy; for (seq_size_type j = 0; j < inL.size(); ++j) { - if (!inL[j] && !get(diG, iG_bimap.left.at(j)) - && !get(dvG, vG_bimap.left.at(j))) + if (!inL[j] && !get(diG, iG_bimap.left[j]) + && !get(dvG, vG_bimap.left[j])) { - put(aiG_inL, iG_bimap.left.at(j), true); - put(avG_inL, vG_bimap.left.at(j), true); + put(aiG_inL, iG_bimap.left[j], true); + put(avG_inL, vG_bimap.left[j], true); undirected_dfs( make_filtered_graph(iG, @@ -274,14 +305,14 @@ namespace detail iG_buf.pop(); while (!vG_buf.empty()) vG_buf.pop(); - put(diG, iG_bimap.left.at(j), true); - put(dvG, vG_bimap.left.at(j), true); - iG_buf_copy.push(iG_bimap.left.at(j)); - vG_buf_copy.push(vG_bimap.left.at(j)); + put(diG, iG_bimap.left[j], true); + put(dvG, vG_bimap.left[j], true); + iG_buf_copy.push(iG_bimap.left[j]); + vG_buf_copy.push(vG_bimap.left[j]); } - put(aiG_inL, iG_bimap.left.at(j), false); - put(avG_inL, vG_bimap.left.at(j), false); + put(aiG_inL, iG_bimap.left[j], false); + put(avG_inL, vG_bimap.left[j], false); } } @@ -294,7 +325,7 @@ namespace detail { put(diG, iG_buf_copy.top(), false); put(dvG, - vG_bimap.left.at(iG_bimap.right.at(iG_buf_copy.top())), + vG_bimap.left[iG_bimap.right.at(iG_buf_copy.top())], false); iG_buf_copy.pop(); } @@ -302,17 +333,17 @@ namespace detail { put(dvG, vG_buf_copy.top(), false); put(diG, - iG_bimap.left.at(vG_bimap.right.at(vG_buf_copy.top())), + iG_bimap.left[vG_bimap.right.at(vG_buf_copy.top())], false); vG_buf_copy.pop(); } inL[m] = false; - put(aiG_inL, iG_bimap.left.at(m), false); - put(avG_inL, vG_bimap.left.at(m), false); + put(aiG_inL, iG_bimap.left[m], false); + put(avG_inL, vG_bimap.left[m], false); - put(diG, iG_bimap.left.at(m), true); - put(dvG, vG_bimap.left.at(m), true); + put(diG, iG_bimap.left[m], true); + put(dvG, vG_bimap.left[m], true); std::map< vertex_descriptor, edge_descriptor > tree_map; std::map< vertex_descriptor, vertex_descriptor > pred_map; @@ -382,7 +413,7 @@ namespace detail { put(aiG_inL, iG_buf.top(), true); put(avG_inL, - vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())), + vG_bimap.left[iG_bimap.right.at(iG_buf.top())], true); undirected_dfs( @@ -427,7 +458,7 @@ namespace detail put(aiG_inL, iG_buf.top(), false); put(avG_inL, - vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())), + vG_bimap.left[iG_bimap.right.at(iG_buf.top())], false); } iG_buf.pop(); @@ -438,7 +469,7 @@ namespace detail { put(avG_inL, vG_buf.top(), true); put(aiG_inL, - iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())), + iG_bimap.left[vG_bimap.right.at(vG_buf.top())], true); undirected_dfs( @@ -483,7 +514,7 @@ namespace detail put(avG_inL, vG_buf.top(), false); put(aiG_inL, - iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())), + iG_bimap.left[vG_bimap.right.at(vG_buf.top())], false); } vG_buf.pop(); @@ -496,10 +527,7 @@ namespace detail { inL[iG_bimap.right.at(iG_buf_copy.top())] = true; put(aiG_inL, iG_buf_copy.top(), true); - put(avG_inL, - vG_bimap.left.at( - iG_bimap.right.at(iG_buf_copy.top())), - true); + put(avG_inL, vG_bimap.left[ iG_bimap.right.at(iG_buf_copy.top())], true); iG_buf.push(iG_buf_copy.top()); iG_buf_copy.pop(); } @@ -507,10 +535,7 @@ namespace detail { inL[vG_bimap.right.at(vG_buf_copy.top())] = true; put(avG_inL, vG_buf_copy.top(), true); - put(aiG_inL, - iG_bimap.left.at( - vG_bimap.right.at(vG_buf_copy.top())), - true); + put(aiG_inL, iG_bimap.left[ vG_bimap.right.at(vG_buf_copy.top())], true); vG_buf.push(vG_buf_copy.top()); vG_buf_copy.pop(); } @@ -524,24 +549,20 @@ namespace detail { inL[iG_bimap.right.at(iG_buf.top())] = false; put(aiG_inL, iG_buf.top(), false); - put(avG_inL, - vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())), - false); + put(avG_inL, vG_bimap.left[iG_bimap.right.at(iG_buf.top())], false); iG_buf.pop(); } while (!vG_buf.empty()) { inL[vG_bimap.right.at(vG_buf.top())] = false; put(avG_inL, vG_buf.top(), false); - put(aiG_inL, - iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())), - false); + put(aiG_inL, iG_bimap.left[vG_bimap.right.at(vG_buf.top())], false); vG_buf.pop(); } } - put(diG, iG_bimap.left.at(m), false); - put(dvG, vG_bimap.left.at(m), false); + put(diG, iG_bimap.left[m], false); + put(dvG, vG_bimap.left[m], false); } } } @@ -612,10 +633,8 @@ two_graphs_common_spanning_trees(const Graph& iG, Order iG_map, const Graph& vG, if (iG_map.size() != num_edges(iG) || vG_map.size() != num_edges(vG)) return; - typedef bimaps::bimap< bimaps::set_of< int >, - bimaps::set_of< order_value_type > > - bimap_type; - typedef typename bimap_type::value_type bimap_value; + using bimap_type = detail::index_bimap< order_value_type >; + using bimap_value = typename bimap_type::value_type; bimap_type iG_bimap, vG_bimap; for (order_size_type i = 0; i < iG_map.size(); ++i) @@ -698,13 +717,13 @@ two_graphs_common_spanning_trees(const Graph& iG, Order iG_map, const Graph& vG, { if (inL[i]) { - put(aiG_inL, iG_bimap.left.at(i), true); - put(avG_inL, vG_bimap.left.at(i), true); + put(aiG_inL, iG_bimap.left[i], true); + put(avG_inL, vG_bimap.left[i], true); } else { - put(aiG_inL, iG_bimap.left.at(i), false); - put(avG_inL, vG_bimap.left.at(i), false); + put(aiG_inL, iG_bimap.left[i], false); + put(avG_inL, vG_bimap.left[i], false); } } @@ -751,8 +770,8 @@ two_graphs_common_spanning_trees(const Graph& iG, Order iG_map, const Graph& vG, { if (!inL[j]) { - put(aiG_inL, iG_bimap.left.at(j), true); - put(avG_inL, vG_bimap.left.at(j), true); + put(aiG_inL, iG_bimap.left[j], true); + put(avG_inL, vG_bimap.left[j], true); undirected_dfs( make_filtered_graph(iG, @@ -787,12 +806,12 @@ two_graphs_common_spanning_trees(const Graph& iG, Order iG_map, const Graph& vG, iG_buf.pop(); while (!vG_buf.empty()) vG_buf.pop(); - put(diG, iG_bimap.left.at(j), true); - put(dvG, vG_bimap.left.at(j), true); + put(diG, iG_bimap.left[j], true); + put(dvG, vG_bimap.left[j], true); } - put(aiG_inL, iG_bimap.left.at(j), false); - put(avG_inL, vG_bimap.left.at(j), false); + put(aiG_inL, iG_bimap.left[j], false); + put(avG_inL, vG_bimap.left[j], false); } }