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, ...@@ -87,7 +87,8 @@ void predecessor_graph(GraphInterface& gi, GraphInterface& gpi,
boost::any pred_map); boost::any pred_map);
void line_graph(GraphInterface& gi, GraphInterface& lgi, void line_graph(GraphInterface& gi, GraphInterface& lgi,
boost::any edge_index); 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, void vertex_property_union(GraphInterface& ugi, GraphInterface& gi,
boost::any p_vprop, boost::any p_eprop, boost::any p_vprop, boost::any p_eprop,
boost::any uprop, boost::any prop); boost::any uprop, boost::any prop);
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
using namespace graph_tool; using namespace graph_tool;
using namespace boost; using namespace boost;
typedef property_map_type::apply<GraphInterface::vertex_t, typedef property_map_type::apply<int32_t,
GraphInterface::vertex_index_map_t>::type GraphInterface::vertex_index_map_t>::type
vprop_t; vprop_t;
...@@ -45,14 +45,15 @@ struct get_pointers ...@@ -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()); eprop_t eprop(gi.GetEdgeIndex());
run_action<graph_tool::detail::always_directed,mpl::true_>() run_action<graph_tool::detail::always_directed,mpl::true_>()
(ugi, bind<void>(graph_tool::graph_union(), (ugi, bind<void>(graph_tool::graph_union(),
_1, _2, vprop, eprop), _1, _2, vprop, eprop),
get_pointers::apply<graph_tool::detail::always_directed>::type()) get_pointers::apply<graph_tool::detail::always_directed>::type())
(gi.GetGraphView()); (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 ...@@ -36,12 +36,27 @@ struct graph_union
Graph& g = *gp; Graph& g = *gp;
typename graph_traits<Graph>::vertex_iterator v, v_end; typename graph_traits<Graph>::vertex_iterator v, v_end;
for (tie(v,v_end) = vertices(g); v != v_end; ++v) 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; typename graph_traits<Graph>::edge_iterator e, e_end;
for (tie(e,e_end) = edges(g); e != e_end; ++e) for (tie(e,e_end) = edges(g); e != e_end; ++e)
emap[*e] = add_edge(vmap[source(*e,g)], emap[*e] = add_edge(vertex(vmap[source(*e,g)], g),
vmap[target(*e,g)], ug).first; vertex(vmap[target(*e,g)], g), ug).first;
} }
}; };
...@@ -54,7 +69,8 @@ struct property_union ...@@ -54,7 +69,8 @@ struct property_union
UnionProp uprop, boost::any aprop) const UnionProp uprop, boost::any aprop) const
{ {
Graph& g = *gp; 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, dispatch(ug, g, vmap, emap, uprop, prop,
is_same<typename property_traits<UnionProp>::key_type, is_same<typename property_traits<UnionProp>::key_type,
typename graph_traits<Graph>::vertex_descriptor>()); typename graph_traits<Graph>::vertex_descriptor>());
...@@ -67,7 +83,7 @@ struct property_union ...@@ -67,7 +83,7 @@ struct property_union
{ {
typename graph_traits<Graph>::vertex_iterator v, v_end; typename graph_traits<Graph>::vertex_iterator v, v_end;
for (tie(v,v_end) = vertices(g); v != v_end; ++v) 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, template <class UnionGraph, class Graph, class VertexMap, class EdgeMap,
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
using namespace graph_tool; using namespace graph_tool;
using namespace boost; using namespace boost;
typedef property_map_type::apply<GraphInterface::vertex_t,
typedef property_map_type::apply<int32_t,
GraphInterface::vertex_index_map_t>::type GraphInterface::vertex_index_map_t>::type
vprop_t; vprop_t;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
using namespace graph_tool; using namespace graph_tool;
using namespace boost; using namespace boost;
typedef property_map_type::apply<GraphInterface::vertex_t, typedef property_map_type::apply<int32_t,
GraphInterface::vertex_index_map_t>::type GraphInterface::vertex_index_map_t>::type
vprop_t; vprop_t;
...@@ -59,5 +59,3 @@ void vertex_property_union(GraphInterface& ugi, GraphInterface& gi, ...@@ -59,5 +59,3 @@ void vertex_property_union(GraphInterface& ugi, GraphInterface& gi,
writable_vertex_properties()) writable_vertex_properties())
(gi.GetGraphView(), uprop); (gi.GetGraphView(), uprop);
} }
...@@ -729,7 +729,7 @@ def line_graph(g): ...@@ -729,7 +729,7 @@ def line_graph(g):
return lg, vertex_map 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 """Return the union of graphs g1 and g2, composed of all edges and vertices
of g1 and g2, without overlap. of g1 and g2, without overlap.
...@@ -739,6 +739,11 @@ def graph_union(g1, g2, props=None, include=False): ...@@ -739,6 +739,11 @@ def graph_union(g1, g2, props=None, include=False):
First graph in the union. First graph in the union.
g2 : :class:`~graph_tool.Graph` g2 : :class:`~graph_tool.Graph`
Second graph in the union. 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: ``[]``) 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 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 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): ...@@ -783,6 +788,14 @@ def graph_union(g1, g2, props=None, include=False):
props = [] props = []
if not include: if not include:
g1 = Graph(g1) 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.stash_filter(directed=True)
g1.set_directed(True) g1.set_directed(True)
g2.stash_filter(directed=True) g2.stash_filter(directed=True)
...@@ -791,9 +804,10 @@ def graph_union(g1, g2, props=None, include=False): ...@@ -791,9 +804,10 @@ def graph_union(g1, g2, props=None, include=False):
try: try:
vmap, emap = libgraph_tool_generation.graph_union(g1._Graph__graph, vmap, emap = libgraph_tool_generation.graph_union(g1._Graph__graph,
g2._Graph__graph) g2._Graph__graph,
for p in props: _prop("v", g1,
p1, p2 = p intersection))
for p1, p2 in props:
if not include: if not include:
p1 = g1.copy_property(p1) p1 = g1.copy_property(p1)
if p2.value_type() != p1.value_type(): 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