diff --git a/src/graph/topology/Makefile.am b/src/graph/topology/Makefile.am index eca61178ea29326403e7d14cae30b48f30f698b3..d19ece645d98837c4791dc55c1c565b66b153065 100644 --- a/src/graph/topology/Makefile.am +++ b/src/graph/topology/Makefile.am @@ -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 = diff --git a/src/graph/topology/graph_denominator_tree.cc b/src/graph/topology/graph_denominator_tree.cc new file mode 100644 index 0000000000000000000000000000000000000000..faf6b4c9ae38ff235f9d17f82d56b20d81fb0964 --- /dev/null +++ b/src/graph/topology/graph_denominator_tree.cc @@ -0,0 +1,49 @@ +// graph-tool -- a general graph modification and manipulation thingy +// +// Copyright (C) 2007 Tiago de Paula Peixoto +// +// 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 . + +#include "graph_filtering.hh" +#include "graph.hh" +#include "graph_properties.hh" + +#include + +using namespace std; +using namespace boost; +using namespace boost::lambda; +using namespace graph_tool; + +struct get_denominator_tree +{ + template + 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, + GraphInterface::vertex_index_map_t, + mpl::bool_ >::type + pred_properties; + +bool denominator_tree(GraphInterface& gi, size_t entry, boost::any pred_map) +{ + run_action() + (gi, bind(get_denominator_tree(), _1, entry, _2), + pred_properties())(pred_map); +} + diff --git a/src/graph/topology/graph_minimum_spanning_tree.cc b/src/graph/topology/graph_minimum_spanning_tree.cc index e5a09c13a0a9a36034f8e2f2cb730b22905f6261..1d15825f6e415ac12aeb474c7f4f034e1001259b 100644 --- a/src/graph/topology/graph_minimum_spanning_tree.cc +++ b/src/graph/topology/graph_minimum_spanning_tree.cc @@ -19,7 +19,6 @@ #include "graph.hh" #include "graph_properties.hh" -#include #include #include @@ -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::edge_descriptor> - // tree_edges_t; - // tree_edges_t tree_edges; - // back_insert_iterator tree_inserter(tree_edges); - kruskal_minimum_spanning_tree(g, tree_inserter(tree_map), weight_map(weights)); } diff --git a/src/graph/topology/graph_topological_sort.cc b/src/graph/topology/graph_topological_sort.cc new file mode 100644 index 0000000000000000000000000000000000000000..b6d2f7257879eabea6042fa917e71d9db4e9fb9f --- /dev/null +++ b/src/graph/topology/graph_topological_sort.cc @@ -0,0 +1,51 @@ + +// graph-tool -- a general graph modification and manipulation thingy +// +// Copyright (C) 2007 Tiago de Paula Peixoto +// +// 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 . + +#include "graph_filtering.hh" +#include "graph.hh" +#include "graph_properties.hh" + +#include + +using namespace std; +using namespace boost; +using namespace boost::lambda; +using namespace graph_tool; + +struct get_topological_sort +{ + template + void operator()(const Graph& g, vector& sort) const + { + sort.clear(); + topological_sort(g, std::back_inserter(sort)); + } +}; + +void topological_sort(GraphInterface& gi, vector& sort) +{ + try + { + run_action<>() + (gi, bind(get_topological_sort(), _1, ref(sort)))(); + } + catch (not_a_dag& e) + { + throw ValueException("graph is not a directed acylic graph (DAG)."); + } +} diff --git a/src/graph/topology/graph_topology.cc b/src/graph/topology/graph_topology.cc index 0ee7b44d15c769bf2d8d80fd8c9e236ed96594b0..c6415e576298ebd9c06d25fd650c7b8b5dc07446 100644 --- a/src/graph/topology/graph_topology.cc +++ b/src/graph/topology/graph_topology.cc @@ -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& 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); } diff --git a/src/graph/topology/graph_transitive_closure.cc b/src/graph/topology/graph_transitive_closure.cc new file mode 100644 index 0000000000000000000000000000000000000000..bd427cd3a2b567de439f9a453c1558be3ffcfe32 --- /dev/null +++ b/src/graph/topology/graph_transitive_closure.cc @@ -0,0 +1,41 @@ +// graph-tool -- a general graph modification and manipulation thingy +// +// Copyright (C) 2007 Tiago de Paula Peixoto +// +// 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 . + +#include "graph.hh" +#include "graph_filtering.hh" + +#include + +using namespace graph_tool; +using namespace boost; + +struct get_transitive_closure +{ + template + void operator()(Graph& g, TCGraph& tcg) const + { + boost::transitive_closure(g, tcg); + } +}; + + +void transitive_closure(GraphInterface& gi, GraphInterface& tcgi) +{ + run_action() + (gi, bind(get_transitive_closure(), _1, + ref(tcgi.GetGraph())))(); +} diff --git a/src/graph_tool/topology/__init__.py b/src/graph_tool/topology/__init__.py index 936fb427ffad53c586fd06a4b03e32aa51990a60..501fc32a72feaac6340c843748eee8cae4395d71 100644 --- a/src/graph_tool/topology/__init__.py +++ b/src/graph_tool/topology/__init__.py @@ -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