diff --git a/src/graph/graph.hh b/src/graph/graph.hh index b0802ebb191ff5acbe3024a757d1651ed978c73b..07ca3256db3ba698c012729f804746cdcbcabcc0 100644 --- a/src/graph/graph.hh +++ b/src/graph/graph.hh @@ -59,7 +59,8 @@ class GraphInterface public: GraphInterface(); GraphInterface(const GraphInterface& g, bool keep_ref, - python::object ovprops, python::object oeprops); + python::object ovprops, python::object oeprops, + python::object vorder); ~GraphInterface(); // useful enums diff --git a/src/graph/graph_copy.cc b/src/graph/graph_copy.cc index 3f91b4cb060de203c3a438dd89553feaf2db5373..deb9a5a2fa0b41ba00a3b63c1ca122bb312f56d6 100644 --- a/src/graph/graph_copy.cc +++ b/src/graph/graph_copy.cc @@ -83,12 +83,13 @@ struct do_graph_copy { template + class SrcEdgeIndexMap, class OrderMap> void operator()(const GraphSrc& src, GraphTgt& tgt, TgtVertexIndexMap src_vertex_index, SrcVertexIndexMap tgt_vertex_index, TgtEdgeIndexMap, SrcEdgeIndexMap tgt_edge_index, + OrderMap vertex_order, vector,reference_wrapper > >& vprops, vector,reference_wrapper > >& eprops) const { @@ -98,7 +99,8 @@ struct do_graph_copy { if (src_vertex_index[*v] >= index_map.size()) index_map.resize(src_vertex_index[*v]+1); - typename graph_traits::vertex_descriptor new_v = + typename graph_traits::vertex_descriptor new_v = get(vertex_order, *v); + while (new_v >= num_vertices(tgt)) add_vertex(tgt); index_map[src_vertex_index[*v]] = tgt_vertex_index[new_v]; @@ -126,7 +128,8 @@ struct do_graph_copy // copy constructor GraphInterface::GraphInterface(const GraphInterface& gi, bool keep_ref, - python::object ovprops, python::object oeprops) + python::object ovprops, python::object oeprops, + python::object vorder) :_mg(keep_ref ? gi._mg : shared_ptr(new multigraph_t())), _vertex_index(get(vertex_index, *_mg)), _edge_index(get(edge_index_t(), *_mg)), @@ -159,7 +162,7 @@ GraphInterface::GraphInterface(const GraphInterface& gi, bool keep_ref, (const_cast(gi), bind(do_graph_copy(), _1, ref(*_mg), gi._vertex_index, _vertex_index, - gi._edge_index, _edge_index, ref(vprops), - ref(eprops)))(); + gi._edge_index, _edge_index, _2, ref(vprops), + ref(eprops)), vertex_scalar_properties())(avorder); // filters will be copied in python } diff --git a/src/graph_tool/__init__.py b/src/graph_tool/__init__.py index 5104c526dcec0b43cf35bea86ede06906ec31ebc..a8299237a6893b55c74ebe0488b39c42403d8312 100644 --- a/src/graph_tool/__init__.py +++ b/src/graph_tool/__init__.py @@ -1020,6 +1020,10 @@ class Graph(object): ``prune``, to specify a different behavior to vertex, edge, and reversal filters, respectively. + If ``vorder`` is specified, it should correspond to a vertex + :class:`~graph_tool.PropertyMap` specifying the ordering of the vertices in + the copied graph. + The graph is implemented as an `adjacency list`_, where both vertex and edge lists are C++ STL vectors. @@ -1027,7 +1031,7 @@ class Graph(object): """ - def __init__(self, g=None, directed=True, prune=False): + def __init__(self, g=None, directed=True, prune=False, vorder=None): self.__properties = {} self.__known_properties = {} self.__filter_state = {"reversed": False, @@ -1055,6 +1059,11 @@ class Graph(object): for k, v in g.edge_properties.items(): eprops.append([_prop("e", g, v), libcore.any()]) + # The vertex ordering + if vorder is None: + vorder = g.new_vertex_property("int") + vorder.fa = numpy.arange(g.num_vertices()) + # The actual copying of the graph and property maps self.__graph = libcore.GraphInterface(g.__graph, False, vprops, eprops)