Commit c21a36c3 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Implement denominator_tree(), min_spanning_tree() and transitive_closure()

parent c0b0a6b7
......@@ -17,6 +17,9 @@ libgraph_tool_topology_la_LDFLAGS = $(MOD_LDFLAGS)
libgraph_tool_topology_la_SOURCES = \
graph_topology.cc \
graph_isomorphism.cc \
graph_minimum_spanning_tree.cc
graph_minimum_spanning_tree.cc \
graph_denominator_tree.cc \
graph_topological_sort.cc \
graph_transitive_closure.cc
libgraph_tool_topology_la_include_HEADERS =
// 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_filtering.hh"
#include "graph.hh"
#include "graph_properties.hh"
#include <boost/graph/dominator_tree.hpp>
using namespace std;
using namespace boost;
using namespace boost::lambda;
using namespace graph_tool;
struct get_denominator_tree
{
template <class Graph, class PredMap>
void operator()(const Graph& g, size_t entry, PredMap pred_map) const
{
lengauer_tarjan_dominator_tree(g, vertex(entry,g), pred_map);
}
};
typedef property_map_types::apply<mpl::vector<int32_t>,
GraphInterface::vertex_index_map_t,
mpl::bool_<false> >::type
pred_properties;
bool denominator_tree(GraphInterface& gi, size_t entry, boost::any pred_map)
{
run_action<graph_tool::detail::always_directed>()
(gi, bind<void>(get_denominator_tree(), _1, entry, _2),
pred_properties())(pred_map);
}
......@@ -19,7 +19,6 @@
#include "graph.hh"
#include "graph_properties.hh"
#include <boost/lambda/bind.hpp>
#include <boost/graph/kruskal_min_spanning_tree.hpp>
#include <boost/graph/prim_minimum_spanning_tree.hpp>
......@@ -55,11 +54,6 @@ struct get_kruskal_min_span_tree
void operator()(const Graph& g, IndexMap vertex_index, WeightMap weights,
TreeMap tree_map) const
{
// typedef vector<typename graph_traits<Graph>::edge_descriptor>
// tree_edges_t;
// tree_edges_t tree_edges;
// back_insert_iterator<tree_edges_t> tree_inserter(tree_edges);
kruskal_minimum_spanning_tree(g, tree_inserter<TreeMap>(tree_map),
weight_map(weights));
}
......
// 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_filtering.hh"
#include "graph.hh"
#include "graph_properties.hh"
#include <boost/graph/topological_sort.hpp>
using namespace std;
using namespace boost;
using namespace boost::lambda;
using namespace graph_tool;
struct get_topological_sort
{
template <class Graph>
void operator()(const Graph& g, vector<int32_t>& sort) const
{
sort.clear();
topological_sort(g, std::back_inserter(sort));
}
};
void topological_sort(GraphInterface& gi, vector<int32_t>& sort)
{
try
{
run_action<>()
(gi, bind<void>(get_topological_sort(), _1, ref(sort)))();
}
catch (not_a_dag& e)
{
throw ValueException("graph is not a directed acylic graph (DAG).");
}
}
......@@ -31,9 +31,18 @@ bool get_kruskal_spanning_tree(GraphInterface& gi, boost::any weight_map,
bool get_prim_spanning_tree(GraphInterface& gi, size_t root,
boost::any weight_map, boost::any tree_map);
void topological_sort(GraphInterface& gi, vector<int32_t>& sort);
bool denominator_tree(GraphInterface& gi, size_t entry, boost::any pred_map);
void transitive_closure(GraphInterface& gi, GraphInterface& tcgi);
BOOST_PYTHON_MODULE(libgraph_tool_topology)
{
def("check_isomorphism", &check_isomorphism);
def("get_kruskal_spanning_tree", &get_kruskal_spanning_tree);
def("get_prim_spanning_tree", &get_prim_spanning_tree);
def("topological_sort", &topological_sort);
def("denominator_tree", &denominator_tree);
def("transitive_closure", &transitive_closure);
}
// 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 <boost/graph/transitive_closure.hpp>
using namespace graph_tool;
using namespace boost;
struct get_transitive_closure
{
template <class Graph, class TCGraph>
void operator()(Graph& g, TCGraph& tcg) const
{
boost::transitive_closure(g, tcg);
}
};
void transitive_closure(GraphInterface& gi, GraphInterface& tcgi)
{
run_action<graph_tool::detail::always_directed>()
(gi, bind<void>(get_transitive_closure(), _1,
ref(tcgi.GetGraph())))();
}
......@@ -24,9 +24,12 @@
from .. dl_import import dl_import
dl_import("import libgraph_tool_topology")
from .. core import _prop
from .. core import _prop, Vector_int32_t, _check_prop_writable, \
_check_prop_scalar, Graph
import random, sys
__all__ = ["isomorphism", "min_spanning_tree"]
__all__ = ["isomorphism", "min_spanning_tree", "denominator_tree",
"topological_sort", "transitive_closure", "label_components",
"label_biconnected_components"]
def isomorphism(g1, g2, isomap=None):
if isomap == None:
......@@ -55,3 +58,110 @@ def min_spanning_tree(g, weights=None, root=None, tree_map=None):
_prop("e", g, tree_map))
g.pop_filter(directed=True)
return tree_map
def denominator_tree(g, root, pred_map=None):
if pred_map == None:
pred_map = g.new_vertex_property("int32_t")
if pred_map.value_type() != "int32_t":
raise ValueError("vertex property 'pred_map' must be of value type" +
" int32_t.")
if not g.is_directed():
raise ValueError("denominator tree requires a directed graph.")
libgraph_tool_topology.\
denominator_tree(g._Graph__graph, int(root),
_prop("v", g, pred_map))
return pred_map
def topological_sort(g):
topological_order = Vector_int32_t()
libgraph_tool_topology.\
topological_sort(g._Graph__graph, topological_order)
return topological_order
<<<<<<< HEAD
=======
def transitive_closure(g):
if not g.is_directed():
raise ValueError("graph must be directed for transitive closure.")
tg = Graph()
libgraph_tool_topology.transitive_closure(g._Graph__graph,
tg._Graph__graph)
return tg
def label_components(g, vprop=None, directed=None):
"""
Labels the components to which each vertex in the graph belongs. If the
graph is directed, it finds the strongly connected components.
Parameters
----------
g : Graph
Graph to be used.
vprop : PropertyMap (optional, default: None)
Vertex property to store the component labels. If none is supplied, one
is created.
directed : bool (optional, default:None)
Treat graph as directed or not, independently of its actual
directionality.
Returns
-------
comp : PropertyMap
Vertex property map with component labels.
Notes
-----
The components are arbitrarily labeled from 0 to N-1, where N is the total
number of components.
The algorithm runs in :math:`O(|V| + |E|)` time.
Examples
--------
>>> g = gt.random_graph(100, lambda: (1, 1), seed=42)
>>> comp = gt.label_components(g)
>>> print comp.get_array()
[0 1 2 3 4 0 3 3 4 4 2 3 4 0 3 3 3 3 0 3 2 1 3 0 0 2 2 3 3 3 0 1 2 3 2 3 0
1 0 5 5 1 4 2 2 1 0 3 3 3 3 3 3 0 0 3 4 2 3 2 5 5 0 2 1 0 3 2 0 3 3 0 4 3
2 6 2 2 1 3 1 1 0 3 0 1 3 0 3 0 2 0 2 2 0 6 1 1 0 2]
"""
if vprop == None:
vprop = g.new_vertex_property("int32_t")
_check_prop_writable(vprop, name="vprop")
_check_prop_scalar(vprop, name="vprop")
if directed != None:
g.stash_filter(directed=True)
g.set_directed(directed)
libgraph_tool_topology.\
label_components(g._Graph__graph, _prop("v", g, vprop))
if directed != None:
g.pop_filter(directed=True)
return vprop
def label_biconnected_components(g, eprop=None, vprop=None):
if vprop == None:
vprop = g.new_vertex_property("bool")
if eprop == None:
eprop = g.new_edge_property("int32_t")
_check_prop_writable(vprop, name="vprop")
_check_prop_scalar(vprop, name="vprop")
_check_prop_writable(eprop, name="eprop")
_check_prop_scalar(eprop, name="eprop")
g.stash_filter(directed=True)
g.set_directed(False)
nc = libgraph_tool_topology.\
label_biconnected_components(g._Graph__graph, _prop("e", g, eprop),
_prop("v", g, vprop))
g.pop_filter(directed=True)
return eprop, vprop, nc
>>>>>>> 3b8ab1b... merge transitive closure
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