Commit 0ac9b1f6 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Implement graph_union()

This returns the union of two graphs, and optionally specified property
maps.
parent 389812f4
......@@ -18,9 +18,16 @@ libgraph_tool_generation_la_SOURCES = \
graph_generation.cc \
graph_rewiring.cc \
graph_predecessor.cc \
graph_line_graph.cc
graph_line_graph.cc \
graph_union.cc \
graph_union_vprop.cc \
graph_union_eprop.cc
libgraph_tool_generation_la_include_HEADERS = \
graph_generation.hh \
graph_rewiring.hh
graph_rewiring.hh \
graph_union.hh
\ No newline at end of file
......@@ -97,6 +97,13 @@ 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);
void vertex_property_union(GraphInterface& ugi, GraphInterface& gi,
boost::any p_vprop, boost::any p_eprop,
boost::any uprop, boost::any prop);
void edge_property_union(GraphInterface& ugi, GraphInterface& gi,
boost::any p_vprop, boost::any p_eprop,
boost::any uprop, boost::any prop);
using namespace boost::python;
......@@ -106,4 +113,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_generation)
def("random_rewire", &random_rewire);
def("predecessor_graph", &predecessor_graph);
def("line_graph", &line_graph);
def("graph_union", &graph_union);
def("vertex_property_union", &vertex_property_union);
def("edge_property_union", &edge_property_union);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007 Tiago de Paula Peixoto <tiago@forked.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph.hh"
#include "graph_filtering.hh"
#include "graph_union.hh"
#include <boost/bind.hpp>
#include <boost/python/extract.hpp>
using namespace graph_tool;
using namespace boost;
typedef property_map_type::apply<GraphInterface::vertex_t,
GraphInterface::vertex_index_map_t>::type
vprop_t;
typedef property_map_type::apply<GraphInterface::edge_t,
GraphInterface::edge_index_map_t>::type
eprop_t;
struct get_pointers
{
template <class List>
struct apply
{
typedef typename mpl::transform<List,
mpl::quote1<add_pointer> >::type type;
};
};
python::tuple graph_union(GraphInterface& ugi, GraphInterface& gi)
{
vprop_t vprop(gi.GetVertexIndex());
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));
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007 Tiago de Paula Peixoto <tiago@forked.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef GRAPH_REWIRING_HH
#define GRAPH_REWIRING_HH
#include <tr1/unordered_set>
#include <tr1/random>
#include <boost/functional/hash.hpp>
#include <boost/vector_property_map.hpp>
#include "graph.hh"
#include "graph_filtering.hh"
#include "graph_util.hh"
namespace graph_tool
{
using namespace std;
using namespace boost;
struct graph_union
{
template <class UnionGraph, class Graph, class VertexMap, class EdgeMap>
void operator()(UnionGraph& ug, Graph* gp, VertexMap vmap, EdgeMap emap)
const
{
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);
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;
}
};
struct property_union
{
template <class UnionGraph, class Graph, class VertexMap, class EdgeMap,
class UnionProp>
void operator()(UnionGraph& ug, Graph* gp, VertexMap vmap, EdgeMap emap,
UnionProp uprop, boost::any aprop) const
{
Graph& g = *gp;
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>());
}
template <class UnionGraph, class Graph, class VertexMap, class EdgeMap,
class UnionProp, class Prop>
void dispatch(UnionGraph& ug, Graph& g, VertexMap vmap, EdgeMap emap,
UnionProp uprop, Prop prop, mpl::true_) const
{
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];
}
template <class UnionGraph, class Graph, class VertexMap, class EdgeMap,
class UnionProp, class Prop>
void dispatch(UnionGraph& ug, Graph& g, VertexMap vmap, EdgeMap emap,
UnionProp uprop, Prop prop, mpl::false_) const
{
typename graph_traits<Graph>::edge_iterator e, e_end;
for (tie(e,e_end) = edges(g); e != e_end; ++e)
uprop[emap[*e]] = prop[*e];
}
};
} // graph_tool namespace
#endif // GRAPH_REWIRING_HH
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007 Tiago de Paula Peixoto <tiago@forked.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph.hh"
#include "graph_filtering.hh"
#include "graph_union.hh"
#include <boost/bind.hpp>
#include <boost/python/extract.hpp>
using namespace graph_tool;
using namespace boost;
typedef property_map_type::apply<GraphInterface::vertex_t,
GraphInterface::vertex_index_map_t>::type
vprop_t;
typedef property_map_type::apply<GraphInterface::edge_t,
GraphInterface::edge_index_map_t>::type
eprop_t;
struct get_pointers
{
template <class List>
struct apply
{
typedef typename mpl::transform<List,
mpl::quote1<add_pointer> >::type type;
};
};
void edge_property_union(GraphInterface& ugi, GraphInterface& gi,
boost::any p_vprop, boost::any p_eprop,
boost::any uprop, boost::any prop)
{
vprop_t vprop = any_cast<vprop_t>(p_vprop);
eprop_t eprop = any_cast<eprop_t>(p_eprop);
run_action<graph_tool::detail::always_directed,mpl::true_>()
(ugi, bind<void>(graph_tool::property_union(),
_1, _2, vprop, eprop, _3, prop),
get_pointers::apply<graph_tool::detail::always_directed>::type(),
writable_edge_properties())
(gi.GetGraphView(), uprop);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007 Tiago de Paula Peixoto <tiago@forked.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph.hh"
#include "graph_filtering.hh"
#include "graph_union.hh"
#include <boost/bind.hpp>
#include <boost/python/extract.hpp>
using namespace graph_tool;
using namespace boost;
typedef property_map_type::apply<GraphInterface::vertex_t,
GraphInterface::vertex_index_map_t>::type
vprop_t;
typedef property_map_type::apply<GraphInterface::edge_t,
GraphInterface::edge_index_map_t>::type
eprop_t;
struct get_pointers
{
template <class List>
struct apply
{
typedef typename mpl::transform<List,
mpl::quote1<add_pointer> >::type type;
};
};
void vertex_property_union(GraphInterface& ugi, GraphInterface& gi,
boost::any p_vprop, boost::any p_eprop,
boost::any uprop, boost::any prop)
{
vprop_t vprop = any_cast<vprop_t>(p_vprop);
eprop_t eprop = any_cast<eprop_t>(p_eprop);
run_action<graph_tool::detail::always_directed,mpl::true_>()
(ugi, bind<void>(graph_tool::property_union(),
_1, _2, vprop, eprop, _3, prop),
get_pointers::apply<graph_tool::detail::always_directed>::type(),
writable_vertex_properties())
(gi.GetGraphView(), uprop);
}
......@@ -27,7 +27,8 @@ dl_import("import libgraph_tool_generation")
from .. core import Graph, _check_prop_scalar, _prop
import sys, numpy
__all__ = ["random_graph", "random_rewire", "predecessor_tree", "line_graph"]
__all__ = ["random_graph", "random_rewire", "predecessor_tree", "line_graph",
"graph_union"]
def _corr_wrap(i, j, corr):
return corr(i[1], j[1])
......@@ -397,3 +398,43 @@ def line_graph(g):
lg._Graph__graph,
_prop("v", lg, vertex_map))
return lg, vertex_map
def graph_union(g1, g2, props=[], include=False):
if not include:
g1 = Graph(g1)
g1.stash_filter(directed=True)
g1.set_directed(True)
g2.stash_filter(directed=True)
g2.set_directed(True)
n_props = []
try:
vmap, emap = libgraph_tool_generation.graph_union(g1._Graph__graph,
g2._Graph__graph)
for p in props:
p1, p2 = p
if not include:
p1 = g1.copy_property(p1)
if p2.value_type() != p1.value_type():
p2 = g2.copy_property(p2, value_type=p1.value_type())
if p1.key_type() == 'v':
libgraph_tool_generation.\
vertex_property_union(g1._Graph__graph, g2._Graph__graph,
vmap, emap,
_prop(p1.key_type(), g1, p1),
_prop(p2.key_type(), g2, p2))
else:
libgraph_tool_generation.\
edge_property_union(g1._Graph__graph, g2._Graph__graph,
vmap, emap,
_prop(p1.key_type(), g1, p1),
_prop(p2.key_type(), g2, p2))
n_props.append(p1)
finally:
g1.pop_filter(directed=True)
g2.pop_filter(directed=True)
if len(n_props) > 0:
return g1, n_props
else:
return g1
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