summaryrefslogtreecommitdiff
path: root/boost/graph/subgraph.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/graph/subgraph.hpp')
-rw-r--r--boost/graph/subgraph.hpp118
1 files changed, 66 insertions, 52 deletions
diff --git a/boost/graph/subgraph.hpp b/boost/graph/subgraph.hpp
index 22706bc617..3d068a5c36 100644
--- a/boost/graph/subgraph.hpp
+++ b/boost/graph/subgraph.hpp
@@ -131,12 +131,24 @@ public:
// copy constructor
subgraph(const subgraph& x)
- : m_parent(x.m_parent), m_edge_counter(x.m_edge_counter)
- , m_global_vertex(x.m_global_vertex), m_global_edge(x.m_global_edge)
+ : m_parent(x.m_parent), m_edge_counter(0)
{
if(x.is_root())
{
- m_graph = x.m_graph;
+ m_graph = x.m_graph;
+ m_edge_counter = x.m_edge_counter;
+ m_global_vertex = x.m_global_vertex;
+ m_global_edge = x.m_global_edge;
+ }
+ else
+ {
+ get_property(*this) = get_property(x);
+ typename subgraph<Graph>::vertex_iterator vi,vi_end;
+ boost::tie(vi, vi_end) = vertices(x);
+ for(; vi != vi_end; ++vi)
+ {
+ add_vertex(x.local_to_global(*vi), *this);
+ }
}
// Do a deep copy (recursive).
// Only the root graph is copied, the subgraphs contain
@@ -144,16 +156,10 @@ public:
typename subgraph<Graph>::children_iterator i,i_end;
boost::tie(i,i_end) = x.children();
for(; i != i_end; ++i)
- {
- subgraph<Graph> child = this->create_subgraph();
- child = *i;
- vertex_iterator vi,vi_end;
- boost::tie(vi,vi_end) = vertices(*i);
- for (;vi!=vi_end;++vi)
- {
- add_vertex(*vi,child);
- }
- }
+ {
+ m_children.push_back(new subgraph<Graph>(*i));
+ m_children.back()->m_parent = this;
+ }
}
@@ -371,46 +377,54 @@ typename subgraph<G>::vertex_descriptor
add_vertex(typename subgraph<G>::vertex_descriptor u_global,
subgraph<G>& g)
{
- BOOST_ASSERT(!g.is_root());
- typename subgraph<G>::vertex_descriptor u_local, v_global;
- typename subgraph<G>::edge_descriptor e_global;
-
- u_local = add_vertex(g.m_graph);
- g.m_global_vertex.push_back(u_global);
- g.m_local_vertex[u_global] = u_local;
-
- subgraph<G>& r = g.root();
-
- // remember edge global and local maps
- {
- typename subgraph<G>::out_edge_iterator ei, ei_end;
- for (boost::tie(ei, ei_end) = out_edges(u_global, r);
- ei != ei_end; ++ei) {
- e_global = *ei;
- v_global = target(e_global, r);
- if (g.find_vertex(v_global).second == true)
- g.local_add_edge(u_local, g.global_to_local(v_global), e_global);
- }
- }
- if (is_directed(g)) { // not necessary for undirected graph
- typename subgraph<G>::vertex_iterator vi, vi_end;
- typename subgraph<G>::out_edge_iterator ei, ei_end;
- for(boost::tie(vi, vi_end) = vertices(r); vi != vi_end; ++vi) {
- v_global = *vi;
- if (v_global == u_global)
- continue; // don't insert self loops twice!
- if (!g.find_vertex(v_global).second)
- continue; // not a subgraph vertex => try next one
- for(boost::tie(ei, ei_end) = out_edges(*vi, r); ei != ei_end; ++ei) {
- e_global = *ei;
- if(target(e_global, r) == u_global) {
- g.local_add_edge(g.global_to_local(v_global), u_local, e_global);
- }
+ BOOST_ASSERT(!g.is_root());
+ typename subgraph<G>::vertex_descriptor u_local;
+ bool exists_local;
+ boost::tie(u_local, exists_local) = g.find_vertex(u_global);
+
+ if (!exists_local) {
+ typename subgraph<G>::vertex_descriptor v_global;
+ typename subgraph<G>::edge_descriptor e_global;
+ // call recursion for parent subgraph
+ if (!g.parent().is_root())
+ add_vertex(u_global, g.parent());
+
+ u_local = add_vertex(g.m_graph);
+ g.m_global_vertex.push_back(u_global);
+ g.m_local_vertex[u_global] = u_local;
+
+ subgraph<G>& r = g.root();
+
+ // remember edge global and local maps
+ {
+ typename subgraph<G>::out_edge_iterator ei, ei_end;
+ for (boost::tie(ei, ei_end) = out_edges(u_global, r);
+ ei != ei_end; ++ei) {
+ e_global = *ei;
+ v_global = target(e_global, r);
+ if (g.find_vertex(v_global).second == true)
+ g.local_add_edge(u_local, g.global_to_local(v_global), e_global);
}
- }
- }
-
- return u_local;
+ }
+ if (is_directed(g)) { // not necessary for undirected graph
+ typename subgraph<G>::vertex_iterator vi, vi_end;
+ typename subgraph<G>::out_edge_iterator ei, ei_end;
+ for(boost::tie(vi, vi_end) = vertices(r); vi != vi_end; ++vi) {
+ v_global = *vi;
+ if (v_global == u_global)
+ continue; // don't insert self loops twice!
+ if (!g.find_vertex(v_global).second)
+ continue; // not a subgraph vertex => try next one
+ for(boost::tie(ei, ei_end) = out_edges(*vi, r); ei != ei_end; ++ei) {
+ e_global = *ei;
+ if(target(e_global, r) == u_global) {
+ g.local_add_edge(g.global_to_local(v_global), u_local, e_global);
+ }
+ }
+ }
+ }
+ }
+ return u_local;
}
// NOTE: Descriptors are local unless otherwise noted.