Commit 7b2aa166 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Implement vertex intersection in graph_union()

parent ee4d43cf
......@@ -87,7 +87,8 @@ void predecessor_graph(GraphInterface& gi, GraphInterface& gpi,
boost::any pred_map);
void line_graph(GraphInterface& gi, GraphInterface& lgi,
boost::any edge_index);
python::tuple graph_union(GraphInterface& ugi, GraphInterface& gi);
python::tuple graph_union(GraphInterface& ugi, GraphInterface& gi,
boost::any avprop);
void vertex_property_union(GraphInterface& ugi, GraphInterface& gi,
boost::any p_vprop, boost::any p_eprop,
boost::any uprop, boost::any prop);
......
......@@ -27,7 +27,7 @@
using namespace graph_tool;
using namespace boost;
typedef property_map_type::apply<GraphInterface::vertex_t,
typedef property_map_type::apply<int32_t,
GraphInterface::vertex_index_map_t>::type
vprop_t;
......@@ -45,14 +45,15 @@ struct get_pointers
};
};
python::tuple graph_union(GraphInterface& ugi, GraphInterface& gi)
python::tuple graph_union(GraphInterface& ugi, GraphInterface& gi,
boost::any avprop)
{
vprop_t vprop(gi.GetVertexIndex());
vprop_t vprop = boost::any_cast<vprop_t>(avprop);
eprop_t eprop(gi.GetEdgeIndex());
run_action<graph_tool::detail::always_directed,mpl::true_>()
(ugi, bind<void>(graph_tool::graph_union(),
_1, _2, vprop, eprop),
get_pointers::apply<graph_tool::detail::always_directed>::type())
(gi.GetGraphView());
return python::make_tuple(boost::any(vprop),boost::any(eprop));
return python::make_tuple(avprop, boost::any(eprop));
}
......@@ -36,12 +36,27 @@ struct graph_union
Graph& g = *gp;
typename graph_traits<Graph>::vertex_iterator v, v_end;
for (tie(v,v_end) = vertices(g); v != v_end; ++v)
vmap[*v] = add_vertex(ug);
{
if (vmap[*v] == 0)
{
vmap[*v] = add_vertex(ug);
}
else
{
typename graph_traits<UnionGraph>::vertex_descriptor w =
vertex(vmap[*v] - 1, ug);
if (w == graph_traits<UnionGraph>::null_vertex() ||
w >= num_vertices(g))
vmap[*v] = add_vertex(ug);
else
vmap[*v] = w;
}
}
typename graph_traits<Graph>::edge_iterator e, e_end;
for (tie(e,e_end) = edges(g); e != e_end; ++e)
emap[*e] = add_edge(vmap[source(*e,g)],
vmap[target(*e,g)], ug).first;
emap[*e] = add_edge(vertex(vmap[source(*e,g)], g),
vertex(vmap[target(*e,g)], g), ug).first;
}
};
......@@ -54,7 +69,8 @@ struct property_union
UnionProp uprop, boost::any aprop) const
{
Graph& g = *gp;
UnionProp prop = any_cast<UnionProp>(aprop);
typename UnionProp::checked_t prop =
any_cast<typename UnionProp::checked_t>(aprop);
dispatch(ug, g, vmap, emap, uprop, prop,
is_same<typename property_traits<UnionProp>::key_type,
typename graph_traits<Graph>::vertex_descriptor>());
......@@ -67,7 +83,7 @@ struct property_union
{
typename graph_traits<Graph>::vertex_iterator v, v_end;
for (tie(v,v_end) = vertices(g); v != v_end; ++v)
uprop[vmap[*v]] = prop[*v];
uprop[vertex(vmap[*v], g)] = prop[*v];
}
template <class UnionGraph, class Graph, class VertexMap, class EdgeMap,
......
......@@ -28,7 +28,8 @@
using namespace graph_tool;
using namespace boost;
typedef property_map_type::apply<GraphInterface::vertex_t,
typedef property_map_type::apply<int32_t,
GraphInterface::vertex_index_map_t>::type
vprop_t;
......
......@@ -27,7 +27,7 @@
using namespace graph_tool;
using namespace boost;
typedef property_map_type::apply<GraphInterface::vertex_t,
typedef property_map_type::apply<int32_t,
GraphInterface::vertex_index_map_t>::type
vprop_t;
......@@ -59,5 +59,3 @@ void vertex_property_union(GraphInterface& ugi, GraphInterface& gi,
writable_vertex_properties())
(gi.GetGraphView(), uprop);
}
......@@ -729,7 +729,7 @@ def line_graph(g):
return lg, vertex_map
def graph_union(g1, g2, props=None, include=False):
def graph_union(g1, g2, intersection=None, props=None, include=False):
"""Return the union of graphs g1 and g2, composed of all edges and vertices
of g1 and g2, without overlap.
......@@ -739,6 +739,11 @@ def graph_union(g1, g2, props=None, include=False):
First graph in the union.
g2 : :class:`~graph_tool.Graph`
Second graph in the union.
intersection : :class:`~graph_tool.PropertyMap` (optional, default: ``None``)
Vertex property map owned by `g1` which maps each of each of its vertices
to vertex indexes belonging to `g2`. Negative values mean no mapping
exists, and thus both vertices in `g1` and `g2` will be present in the
union graph.
props : list of tuples of :class:`~graph_tool.PropertyMap` (optional, default: ``[]``)
Each element in this list must be a tuple of two PropertyMap objects. The
first element must be a property of `g1`, and the second of `g2`. The
......@@ -783,6 +788,14 @@ def graph_union(g1, g2, props=None, include=False):
props = []
if not include:
g1 = Graph(g1)
if intersection is None:
intersection = g1.new_vertex_property("int32_t")
intersection.a = 0
else:
intersection = intersection.copy("int32_t")
intersection.a[intersection.a >= 0] += 1
intersection.a[intersection.a < 0] = 0
g1.stash_filter(directed=True)
g1.set_directed(True)
g2.stash_filter(directed=True)
......@@ -791,9 +804,10 @@ def graph_union(g1, g2, props=None, include=False):
try:
vmap, emap = libgraph_tool_generation.graph_union(g1._Graph__graph,
g2._Graph__graph)
for p in props:
p1, p2 = p
g2._Graph__graph,
_prop("v", g1,
intersection))
for p1, p2 in props:
if not include:
p1 = g1.copy_property(p1)
if p2.value_type() != p1.value_type():
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment