123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852 |
- // Copyright (C) 2012, Michele Caini.
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- // Two Graphs Common Spanning Trees Algorithm
- // Based on academic article of Mint, Read and Tarjan
- // Efficient Algorithm for Common Spanning Tree Problem
- // Electron. Lett., 28 April 1983, Volume 19, Issue 9, p.346-347
- #ifndef BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP
- #define BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP
- #include <boost/config.hpp>
- #include <boost/bimap.hpp>
- #include <boost/type_traits.hpp>
- #include <boost/concept/requires.hpp>
- #include <boost/graph/graph_traits.hpp>
- #include <boost/graph/undirected_dfs.hpp>
- #include <boost/graph/connected_components.hpp>
- #include <boost/graph/filtered_graph.hpp>
- #include <vector>
- #include <stack>
- #include <map>
- namespace boost
- {
- namespace detail
- {
- template < typename TreeMap, typename PredMap, typename DistMap,
- typename LowMap, typename Buffer >
- struct bridges_visitor : public default_dfs_visitor
- {
- bridges_visitor(TreeMap tree, PredMap pred, DistMap dist, LowMap low,
- Buffer& buffer)
- : mTree(tree), mPred(pred), mDist(dist), mLow(low), mBuffer(buffer)
- {
- mNum = -1;
- }
- template < typename Vertex, typename Graph >
- void initialize_vertex(const Vertex& u, const Graph& g)
- {
- put(mPred, u, u);
- put(mDist, u, -1);
- }
- template < typename Vertex, typename Graph >
- void discover_vertex(const Vertex& u, const Graph& g)
- {
- put(mDist, u, ++mNum);
- put(mLow, u, get(mDist, u));
- }
- template < typename Edge, typename Graph >
- void tree_edge(const Edge& e, const Graph& g)
- {
- put(mPred, target(e, g), source(e, g));
- put(mTree, target(e, g), e);
- }
- template < typename Edge, typename Graph >
- void back_edge(const Edge& e, const Graph& g)
- {
- put(mLow, source(e, g),
- (std::min)(get(mLow, source(e, g)), get(mDist, target(e, g))));
- }
- template < typename Vertex, typename Graph >
- void finish_vertex(const Vertex& u, const Graph& g)
- {
- Vertex parent = get(mPred, u);
- if (get(mLow, u) > get(mDist, parent))
- mBuffer.push(get(mTree, u));
- put(mLow, parent, (std::min)(get(mLow, parent), get(mLow, u)));
- }
- TreeMap mTree;
- PredMap mPred;
- DistMap mDist;
- LowMap mLow;
- Buffer& mBuffer;
- int mNum;
- };
- template < typename Buffer >
- struct cycle_finder : public base_visitor< cycle_finder< Buffer > >
- {
- typedef on_back_edge event_filter;
- cycle_finder() : mBuffer(0) {}
- cycle_finder(Buffer* buffer) : mBuffer(buffer) {}
- template < typename Edge, typename Graph >
- void operator()(const Edge& e, const Graph& g)
- {
- if (mBuffer)
- mBuffer->push(e);
- }
- Buffer* mBuffer;
- };
- template < typename DeletedMap > struct deleted_edge_status
- {
- deleted_edge_status() {}
- deleted_edge_status(DeletedMap map) : mMap(map) {}
- template < typename Edge > bool operator()(const Edge& e) const
- {
- return (!get(mMap, e));
- }
- DeletedMap mMap;
- };
- template < typename InLMap > struct inL_edge_status
- {
- inL_edge_status() {}
- inL_edge_status(InLMap map) : mMap(map) {}
- template < typename Edge > bool operator()(const Edge& e) const
- {
- return get(mMap, e);
- }
- InLMap mMap;
- };
- 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 > >
- iG_bimap,
- Map aiG_inL, Map diG, const Graph& vG,
- bimap< bimaps::set_of< int >,
- bimaps::set_of< typename graph_traits< Graph >::edge_descriptor > >
- vG_bimap,
- Map avG_inL, Map dvG, Func func, Seq inL)
- {
- typedef graph_traits< Graph > GraphTraits;
- typedef typename GraphTraits::vertex_descriptor vertex_descriptor;
- typedef typename GraphTraits::edge_descriptor edge_descriptor;
- typedef typename Seq::size_type seq_size_type;
- int edges = num_vertices(iG) - 1;
- //
- // [ Michele Caini ]
- //
- // Using the condition (edges != 0) leads to the accidental submission
- // of
- // sub-graphs ((V-1+1)-fake-tree, named here fat-tree).
- // Remove this condition is a workaround for the problem of fat-trees.
- // Please do not add that condition, even if it improves performance.
- //
- // Here is proposed the previous guard (that was wrong):
- // for(seq_size_type i = 0; (i < inL.size()) && (edges != 0); ++i)
- //
- {
- for (seq_size_type i = 0; i < inL.size(); ++i)
- if (inL[i])
- --edges;
- if (edges < 0)
- return;
- }
- bool is_tree = (edges == 0);
- if (is_tree)
- {
- func(inL);
- }
- else
- {
- std::map< vertex_descriptor, default_color_type > vertex_color;
- std::map< edge_descriptor, default_color_type > edge_color;
- std::stack< edge_descriptor > iG_buf, vG_buf;
- bool found = false;
- 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)))
- {
- put(aiG_inL, iG_bimap.left.at(j), true);
- put(avG_inL, vG_bimap.left.at(j), true);
- undirected_dfs(
- make_filtered_graph(iG,
- detail::inL_edge_status< associative_property_map<
- std::map< edge_descriptor, bool > > >(aiG_inL)),
- make_dfs_visitor(detail::cycle_finder<
- std::stack< edge_descriptor > >(&iG_buf)),
- associative_property_map<
- std::map< vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map<
- std::map< edge_descriptor, default_color_type > >(
- edge_color));
- undirected_dfs(
- make_filtered_graph(vG,
- detail::inL_edge_status< associative_property_map<
- std::map< edge_descriptor, bool > > >(avG_inL)),
- make_dfs_visitor(detail::cycle_finder<
- std::stack< edge_descriptor > >(&vG_buf)),
- associative_property_map<
- std::map< vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map<
- std::map< edge_descriptor, default_color_type > >(
- edge_color));
- if (iG_buf.empty() && vG_buf.empty())
- {
- inL[j] = true;
- found = true;
- m = j;
- }
- else
- {
- while (!iG_buf.empty())
- 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);
- }
- }
- }
- if (found)
- {
- 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)))
- {
- put(aiG_inL, iG_bimap.left.at(j), true);
- put(avG_inL, vG_bimap.left.at(j), true);
- undirected_dfs(
- make_filtered_graph(iG,
- detail::inL_edge_status<
- associative_property_map<
- std::map< edge_descriptor, bool > > >(
- aiG_inL)),
- make_dfs_visitor(detail::cycle_finder<
- std::stack< edge_descriptor > >(&iG_buf)),
- associative_property_map< std::map<
- vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map< std::map< edge_descriptor,
- default_color_type > >(edge_color));
- undirected_dfs(
- make_filtered_graph(vG,
- detail::inL_edge_status<
- associative_property_map<
- std::map< edge_descriptor, bool > > >(
- avG_inL)),
- make_dfs_visitor(detail::cycle_finder<
- std::stack< edge_descriptor > >(&vG_buf)),
- associative_property_map< std::map<
- vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map< std::map< edge_descriptor,
- default_color_type > >(edge_color));
- if (!iG_buf.empty() || !vG_buf.empty())
- {
- while (!iG_buf.empty())
- 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(aiG_inL, iG_bimap.left.at(j), false);
- put(avG_inL, vG_bimap.left.at(j), false);
- }
- }
- // REC
- detail::rec_two_graphs_common_spanning_trees< Graph, Func, Seq,
- Map >(iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL,
- dvG, func, inL);
- while (!iG_buf_copy.empty())
- {
- put(diG, iG_buf_copy.top(), false);
- put(dvG,
- vG_bimap.left.at(iG_bimap.right.at(iG_buf_copy.top())),
- false);
- iG_buf_copy.pop();
- }
- while (!vG_buf_copy.empty())
- {
- put(dvG, vG_buf_copy.top(), false);
- put(diG,
- iG_bimap.left.at(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(diG, iG_bimap.left.at(m), true);
- put(dvG, vG_bimap.left.at(m), true);
- std::map< vertex_descriptor, edge_descriptor > tree_map;
- std::map< vertex_descriptor, vertex_descriptor > pred_map;
- std::map< vertex_descriptor, int > dist_map, low_map;
- detail::bridges_visitor<
- associative_property_map<
- std::map< vertex_descriptor, edge_descriptor > >,
- associative_property_map<
- std::map< vertex_descriptor, vertex_descriptor > >,
- associative_property_map<
- std::map< vertex_descriptor, int > >,
- associative_property_map<
- std::map< vertex_descriptor, int > >,
- std::stack< edge_descriptor > >
- iG_vis(associative_property_map<
- std::map< vertex_descriptor, edge_descriptor > >(
- tree_map),
- associative_property_map<
- std::map< vertex_descriptor, vertex_descriptor > >(
- pred_map),
- associative_property_map<
- std::map< vertex_descriptor, int > >(dist_map),
- associative_property_map<
- std::map< vertex_descriptor, int > >(low_map),
- iG_buf),
- vG_vis(associative_property_map<
- std::map< vertex_descriptor, edge_descriptor > >(
- tree_map),
- associative_property_map<
- std::map< vertex_descriptor, vertex_descriptor > >(
- pred_map),
- associative_property_map<
- std::map< vertex_descriptor, int > >(dist_map),
- associative_property_map<
- std::map< vertex_descriptor, int > >(low_map),
- vG_buf);
- undirected_dfs(
- make_filtered_graph(iG,
- detail::deleted_edge_status< associative_property_map<
- std::map< edge_descriptor, bool > > >(diG)),
- iG_vis,
- associative_property_map<
- std::map< vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map<
- std::map< edge_descriptor, default_color_type > >(
- edge_color));
- undirected_dfs(
- make_filtered_graph(vG,
- detail::deleted_edge_status< associative_property_map<
- std::map< edge_descriptor, bool > > >(dvG)),
- vG_vis,
- associative_property_map<
- std::map< vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map<
- std::map< edge_descriptor, default_color_type > >(
- edge_color));
- found = false;
- std::stack< edge_descriptor > iG_buf_tmp, vG_buf_tmp;
- while (!iG_buf.empty() && !found)
- {
- if (!inL[iG_bimap.right.at(iG_buf.top())])
- {
- put(aiG_inL, iG_buf.top(), true);
- put(avG_inL,
- vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())),
- true);
- undirected_dfs(
- make_filtered_graph(iG,
- detail::inL_edge_status<
- associative_property_map<
- std::map< edge_descriptor, bool > > >(
- aiG_inL)),
- make_dfs_visitor(detail::cycle_finder<
- std::stack< edge_descriptor > >(&iG_buf_tmp)),
- associative_property_map< std::map<
- vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map< std::map< edge_descriptor,
- default_color_type > >(edge_color));
- undirected_dfs(
- make_filtered_graph(vG,
- detail::inL_edge_status<
- associative_property_map<
- std::map< edge_descriptor, bool > > >(
- avG_inL)),
- make_dfs_visitor(detail::cycle_finder<
- std::stack< edge_descriptor > >(&vG_buf_tmp)),
- associative_property_map< std::map<
- vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map< std::map< edge_descriptor,
- default_color_type > >(edge_color));
- if (!iG_buf_tmp.empty() || !vG_buf_tmp.empty())
- {
- found = true;
- }
- else
- {
- while (!iG_buf_tmp.empty())
- iG_buf_tmp.pop();
- while (!vG_buf_tmp.empty())
- vG_buf_tmp.pop();
- iG_buf_copy.push(iG_buf.top());
- }
- put(aiG_inL, iG_buf.top(), false);
- put(avG_inL,
- vG_bimap.left.at(iG_bimap.right.at(iG_buf.top())),
- false);
- }
- iG_buf.pop();
- }
- while (!vG_buf.empty() && !found)
- {
- if (!inL[vG_bimap.right.at(vG_buf.top())])
- {
- put(avG_inL, vG_buf.top(), true);
- put(aiG_inL,
- iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())),
- true);
- undirected_dfs(
- make_filtered_graph(iG,
- detail::inL_edge_status<
- associative_property_map<
- std::map< edge_descriptor, bool > > >(
- aiG_inL)),
- make_dfs_visitor(detail::cycle_finder<
- std::stack< edge_descriptor > >(&iG_buf_tmp)),
- associative_property_map< std::map<
- vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map< std::map< edge_descriptor,
- default_color_type > >(edge_color));
- undirected_dfs(
- make_filtered_graph(vG,
- detail::inL_edge_status<
- associative_property_map<
- std::map< edge_descriptor, bool > > >(
- avG_inL)),
- make_dfs_visitor(detail::cycle_finder<
- std::stack< edge_descriptor > >(&vG_buf_tmp)),
- associative_property_map< std::map<
- vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map< std::map< edge_descriptor,
- default_color_type > >(edge_color));
- if (!iG_buf_tmp.empty() || !vG_buf_tmp.empty())
- {
- found = true;
- }
- else
- {
- while (!iG_buf_tmp.empty())
- iG_buf_tmp.pop();
- while (!vG_buf_tmp.empty())
- vG_buf_tmp.pop();
- vG_buf_copy.push(vG_buf.top());
- }
- put(avG_inL, vG_buf.top(), false);
- put(aiG_inL,
- iG_bimap.left.at(vG_bimap.right.at(vG_buf.top())),
- false);
- }
- vG_buf.pop();
- }
- if (!found)
- {
- while (!iG_buf_copy.empty())
- {
- 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);
- iG_buf.push(iG_buf_copy.top());
- iG_buf_copy.pop();
- }
- while (!vG_buf_copy.empty())
- {
- 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);
- vG_buf.push(vG_buf_copy.top());
- vG_buf_copy.pop();
- }
- // REC
- detail::rec_two_graphs_common_spanning_trees< Graph, Func,
- Seq, Map >(iG, iG_bimap, aiG_inL, diG, vG, vG_bimap,
- aiG_inL, dvG, func, inL);
- while (!iG_buf.empty())
- {
- 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);
- 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);
- vG_buf.pop();
- }
- }
- put(diG, iG_bimap.left.at(m), false);
- put(dvG, vG_bimap.left.at(m), false);
- }
- }
- }
- } // namespace detail
- template < typename Coll, typename Seq > struct tree_collector
- {
- public:
- BOOST_CONCEPT_ASSERT((BackInsertionSequence< Coll >));
- BOOST_CONCEPT_ASSERT((RandomAccessContainer< Seq >));
- BOOST_CONCEPT_ASSERT((CopyConstructible< Seq >));
- typedef typename Coll::value_type coll_value_type;
- typedef typename Seq::value_type seq_value_type;
- BOOST_STATIC_ASSERT((is_same< coll_value_type, Seq >::value));
- BOOST_STATIC_ASSERT((is_same< seq_value_type, bool >::value));
- tree_collector(Coll& seqs) : mSeqs(seqs) {}
- inline void operator()(Seq seq) { mSeqs.push_back(seq); }
- private:
- Coll& mSeqs;
- };
- template < typename Graph, typename Order, typename Func, typename Seq >
- BOOST_CONCEPT_REQUIRES(
- ((RandomAccessContainer< Order >))((IncidenceGraphConcept< Graph >))(
- (UnaryFunction< Func, void, Seq >))(
- (Mutable_RandomAccessContainer< Seq >))(
- (VertexAndEdgeListGraphConcept< Graph >)),
- (void))
- two_graphs_common_spanning_trees(const Graph& iG, Order iG_map, const Graph& vG,
- Order vG_map, Func func, Seq inL)
- {
- typedef graph_traits< Graph > GraphTraits;
- typedef typename GraphTraits::directed_category directed_category;
- typedef typename GraphTraits::vertex_descriptor vertex_descriptor;
- typedef typename GraphTraits::edge_descriptor edge_descriptor;
- typedef typename GraphTraits::edges_size_type edges_size_type;
- typedef typename GraphTraits::edge_iterator edge_iterator;
- typedef typename Seq::value_type seq_value_type;
- typedef typename Seq::size_type seq_size_type;
- typedef typename Order::value_type order_value_type;
- typedef typename Order::size_type order_size_type;
- BOOST_STATIC_ASSERT((is_same< order_value_type, edge_descriptor >::value));
- BOOST_CONCEPT_ASSERT((Convertible< order_size_type, edges_size_type >));
- BOOST_CONCEPT_ASSERT((Convertible< seq_size_type, edges_size_type >));
- BOOST_STATIC_ASSERT((is_same< seq_value_type, bool >::value));
- BOOST_STATIC_ASSERT((is_same< directed_category, undirected_tag >::value));
- if (num_vertices(iG) != num_vertices(vG))
- return;
- if (inL.size() != num_edges(iG) || inL.size() != num_edges(vG))
- return;
- 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;
- bimap_type iG_bimap, vG_bimap;
- for (order_size_type i = 0; i < iG_map.size(); ++i)
- iG_bimap.insert(bimap_value(i, iG_map[i]));
- for (order_size_type i = 0; i < vG_map.size(); ++i)
- vG_bimap.insert(bimap_value(i, vG_map[i]));
- edge_iterator current, last;
- boost::tuples::tie(current, last) = edges(iG);
- for (; current != last; ++current)
- if (iG_bimap.right.find(*current) == iG_bimap.right.end())
- return;
- boost::tuples::tie(current, last) = edges(vG);
- for (; current != last; ++current)
- if (vG_bimap.right.find(*current) == vG_bimap.right.end())
- return;
- std::stack< edge_descriptor > iG_buf, vG_buf;
- std::map< vertex_descriptor, edge_descriptor > tree_map;
- std::map< vertex_descriptor, vertex_descriptor > pred_map;
- std::map< vertex_descriptor, int > dist_map, low_map;
- detail::bridges_visitor< associative_property_map< std::map<
- vertex_descriptor, edge_descriptor > >,
- associative_property_map<
- std::map< vertex_descriptor, vertex_descriptor > >,
- associative_property_map< std::map< vertex_descriptor, int > >,
- associative_property_map< std::map< vertex_descriptor, int > >,
- std::stack< edge_descriptor > >
- iG_vis(associative_property_map<
- std::map< vertex_descriptor, edge_descriptor > >(tree_map),
- associative_property_map<
- std::map< vertex_descriptor, vertex_descriptor > >(pred_map),
- associative_property_map< std::map< vertex_descriptor, int > >(
- dist_map),
- associative_property_map< std::map< vertex_descriptor, int > >(low_map),
- iG_buf),
- vG_vis(associative_property_map<
- std::map< vertex_descriptor, edge_descriptor > >(tree_map),
- associative_property_map<
- std::map< vertex_descriptor, vertex_descriptor > >(pred_map),
- associative_property_map< std::map< vertex_descriptor, int > >(
- dist_map),
- associative_property_map< std::map< vertex_descriptor, int > >(
- low_map),
- vG_buf);
- std::map< vertex_descriptor, default_color_type > vertex_color;
- std::map< edge_descriptor, default_color_type > edge_color;
- undirected_dfs(iG, iG_vis,
- associative_property_map<
- std::map< vertex_descriptor, default_color_type > >(vertex_color),
- associative_property_map<
- std::map< edge_descriptor, default_color_type > >(edge_color));
- undirected_dfs(vG, vG_vis,
- associative_property_map<
- std::map< vertex_descriptor, default_color_type > >(vertex_color),
- associative_property_map<
- std::map< edge_descriptor, default_color_type > >(edge_color));
- while (!iG_buf.empty())
- {
- inL[iG_bimap.right.at(iG_buf.top())] = true;
- iG_buf.pop();
- }
- while (!vG_buf.empty())
- {
- inL[vG_bimap.right.at(vG_buf.top())] = true;
- vG_buf.pop();
- }
- std::map< edge_descriptor, bool > iG_inL, vG_inL;
- associative_property_map< std::map< edge_descriptor, bool > > aiG_inL(
- iG_inL),
- avG_inL(vG_inL);
- for (seq_size_type i = 0; i < inL.size(); ++i)
- {
- if (inL[i])
- {
- put(aiG_inL, iG_bimap.left.at(i), true);
- put(avG_inL, vG_bimap.left.at(i), true);
- }
- else
- {
- put(aiG_inL, iG_bimap.left.at(i), false);
- put(avG_inL, vG_bimap.left.at(i), false);
- }
- }
- undirected_dfs(
- make_filtered_graph(iG,
- detail::inL_edge_status<
- associative_property_map< std::map< edge_descriptor, bool > > >(
- aiG_inL)),
- make_dfs_visitor(
- detail::cycle_finder< std::stack< edge_descriptor > >(&iG_buf)),
- associative_property_map<
- std::map< vertex_descriptor, default_color_type > >(vertex_color),
- associative_property_map<
- std::map< edge_descriptor, default_color_type > >(edge_color));
- undirected_dfs(
- make_filtered_graph(vG,
- detail::inL_edge_status<
- associative_property_map< std::map< edge_descriptor, bool > > >(
- avG_inL)),
- make_dfs_visitor(
- detail::cycle_finder< std::stack< edge_descriptor > >(&vG_buf)),
- associative_property_map<
- std::map< vertex_descriptor, default_color_type > >(vertex_color),
- associative_property_map<
- std::map< edge_descriptor, default_color_type > >(edge_color));
- if (iG_buf.empty() && vG_buf.empty())
- {
- std::map< edge_descriptor, bool > iG_deleted, vG_deleted;
- associative_property_map< std::map< edge_descriptor, bool > > diG(
- iG_deleted);
- associative_property_map< std::map< edge_descriptor, bool > > dvG(
- vG_deleted);
- boost::tuples::tie(current, last) = edges(iG);
- for (; current != last; ++current)
- put(diG, *current, false);
- boost::tuples::tie(current, last) = edges(vG);
- for (; current != last; ++current)
- put(dvG, *current, false);
- for (seq_size_type j = 0; j < inL.size(); ++j)
- {
- if (!inL[j])
- {
- put(aiG_inL, iG_bimap.left.at(j), true);
- put(avG_inL, vG_bimap.left.at(j), true);
- undirected_dfs(
- make_filtered_graph(iG,
- detail::inL_edge_status< associative_property_map<
- std::map< edge_descriptor, bool > > >(aiG_inL)),
- make_dfs_visitor(
- detail::cycle_finder< std::stack< edge_descriptor > >(
- &iG_buf)),
- associative_property_map<
- std::map< vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map<
- std::map< edge_descriptor, default_color_type > >(
- edge_color));
- undirected_dfs(
- make_filtered_graph(vG,
- detail::inL_edge_status< associative_property_map<
- std::map< edge_descriptor, bool > > >(avG_inL)),
- make_dfs_visitor(
- detail::cycle_finder< std::stack< edge_descriptor > >(
- &vG_buf)),
- associative_property_map<
- std::map< vertex_descriptor, default_color_type > >(
- vertex_color),
- associative_property_map<
- std::map< edge_descriptor, default_color_type > >(
- edge_color));
- if (!iG_buf.empty() || !vG_buf.empty())
- {
- while (!iG_buf.empty())
- 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(aiG_inL, iG_bimap.left.at(j), false);
- put(avG_inL, vG_bimap.left.at(j), false);
- }
- }
- int cc = 0;
- std::map< vertex_descriptor, int > com_map;
- cc += connected_components(
- make_filtered_graph(iG,
- detail::deleted_edge_status< associative_property_map<
- std::map< edge_descriptor, bool > > >(diG)),
- associative_property_map< std::map< vertex_descriptor, int > >(
- com_map));
- cc += connected_components(
- make_filtered_graph(vG,
- detail::deleted_edge_status< associative_property_map<
- std::map< edge_descriptor, bool > > >(dvG)),
- associative_property_map< std::map< vertex_descriptor, int > >(
- com_map));
- if (cc != 2)
- return;
- // REC
- detail::rec_two_graphs_common_spanning_trees< Graph, Func, Seq,
- associative_property_map< std::map< edge_descriptor, bool > > >(
- iG, iG_bimap, aiG_inL, diG, vG, vG_bimap, aiG_inL, dvG, func, inL);
- }
- }
- template < typename Graph, typename Func, typename Seq >
- BOOST_CONCEPT_REQUIRES(
- ((IncidenceGraphConcept< Graph >))((EdgeListGraphConcept< Graph >)), (void))
- two_graphs_common_spanning_trees(
- const Graph& iG, const Graph& vG, Func func, Seq inL)
- {
- typedef graph_traits< Graph > GraphTraits;
- typedef typename GraphTraits::edge_descriptor edge_descriptor;
- typedef typename GraphTraits::edge_iterator edge_iterator;
- std::vector< edge_descriptor > iGO, vGO;
- edge_iterator curr, last;
- boost::tuples::tie(curr, last) = edges(iG);
- for (; curr != last; ++curr)
- iGO.push_back(*curr);
- boost::tuples::tie(curr, last) = edges(vG);
- for (; curr != last; ++curr)
- vGO.push_back(*curr);
- two_graphs_common_spanning_trees(iG, iGO, vG, vGO, func, inL);
- }
- } // namespace boost
- #endif // BOOST_GRAPH_TWO_GRAPHS_COMMON_SPANNING_TREES_HPP
|