Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Tiago Peixoto
graph-tool
Commits
6b0e1705
Commit
6b0e1705
authored
Apr 15, 2011
by
Tiago Peixoto
Browse files
Implement label_largest_component() and return label histogram in label_components()
parent
5cbf8593
Changes
3
Show whitespace changes
Inline
Side-by-side
src/graph/topology/graph_components.cc
View file @
6b0e1705
...
...
@@ -20,29 +20,34 @@
#include "graph_components.hh"
#include "numpy_bind.hh"
#include <boost/python.hpp>
using
namespace
std
;
using
namespace
boost
;
using
namespace
graph_tool
;
void
do_label_components
(
GraphInterface
&
gi
,
boost
::
any
prop
)
python
::
object
do_label_components
(
GraphInterface
&
gi
,
boost
::
any
prop
)
{
run_action
<>
()(
gi
,
label_components
(),
vector
<
size_t
>
hist
;
run_action
<>
()(
gi
,
bind
<
void
>
(
label_components
(),
_1
,
_2
,
ref
(
hist
)),
writable_vertex_scalar_properties
())(
prop
);
return
wrap_vector_owned
(
hist
);
}
size_t
do_label_biconnected_components
(
GraphInterface
&
gi
,
boost
::
any
comp
,
python
::
object
do_label_biconnected_components
(
GraphInterface
&
gi
,
boost
::
any
comp
,
boost
::
any
art
)
{
size_t
nc
;
vector
<
size_t
>
hist
;
run_action
<
graph_tool
::
detail
::
never_directed
>
()
(
gi
,
bind
<
void
>
(
label_biconnected_components
(),
_1
,
_2
,
_3
,
ref
(
nc
)),
ref
(
hist
)),
writable_edge_scalar_properties
(),
writable_vertex_scalar_properties
())
(
comp
,
art
);
return
nc
;
return
wrap_vector_owned
(
hist
)
;
}
void
export_components
()
...
...
src/graph/topology/graph_components.hh
View file @
6b0e1705
...
...
@@ -20,22 +20,93 @@
#include <boost/graph/strong_components.hpp>
#include <boost/graph/biconnected_components.hpp>
namespace
graph_tool
{
template
<
class
PropertyMap
>
class
HistogramPropertyMap
;
}
namespace
boost
{
template
<
class
PropertyMap
>
struct
property_traits
<
HistogramPropertyMap
<
PropertyMap
>
>:
public
property_traits
<
PropertyMap
>
{};
}
namespace
graph_tool
{
using
namespace
std
;
using
namespace
boost
;
// this wraps an existing property map, and makes a simple histogram of the
// values (assumed to be an integer type)
template
<
class
PropertyMap
>
class
HistogramPropertyMap
{
public:
typedef
typename
property_traits
<
PropertyMap
>::
value_type
value_type
;
typedef
typename
property_traits
<
PropertyMap
>::
key_type
key_type
;
typedef
typename
property_traits
<
PropertyMap
>::
category
category
;
HistogramPropertyMap
(
PropertyMap
base_map
,
size_t
max
,
vector
<
size_t
>&
hist
)
:
_base_map
(
base_map
),
_max
(
max
),
_hist
(
hist
)
{}
HistogramPropertyMap
(){}
value_type
get
(
const
key_type
&
k
)
const
{
return
boost
::
get
(
_base_map
,
k
);
}
void
put
(
const
key_type
&
k
,
const
value_type
&
v
)
{
boost
::
put
(
_base_map
,
k
,
v
);
vector
<
size_t
>&
h
=
_hist
;
size_t
bin
=
v
;
if
(
bin
>
_max
)
return
;
if
(
bin
>=
h
.
size
())
h
.
resize
(
bin
+
1
);
++
h
[
bin
];
}
private:
PropertyMap
_base_map
;
size_t
_max
;
boost
::
reference_wrapper
<
vector
<
size_t
>
>
_hist
;
};
template
<
class
PropertyMap
>
typename
property_traits
<
PropertyMap
>::
value_type
get
(
const
HistogramPropertyMap
<
PropertyMap
>&
pmap
,
const
typename
property_traits
<
PropertyMap
>::
key_type
&
k
)
{
return
pmap
.
get
(
k
);
}
template
<
class
PropertyMap
>
void
put
(
HistogramPropertyMap
<
PropertyMap
>
pmap
,
const
typename
property_traits
<
PropertyMap
>::
key_type
&
k
,
const
typename
property_traits
<
PropertyMap
>::
value_type
&
val
)
{
pmap
.
put
(
k
,
val
);
}
// this will label the components of a graph to a given vertex property, from
// [0, number of components - 1]
. If the graph is directed the strong
// components are used.
// [0, number of components - 1]
, and keep an histogram. If the graph is
//
directed the strong
components are used.
struct
label_components
{
template
<
class
Graph
,
class
CompMap
>
void
operator
()(
const
Graph
&
g
,
CompMap
comp_map
)
const
void
operator
()(
const
Graph
&
g
,
CompMap
comp_map
,
vector
<
size_t
>&
hist
)
const
{
typedef
typename
graph_traits
<
Graph
>::
directed_category
directed_category
;
get_components
(
g
,
comp_map
,
HistogramPropertyMap
<
CompMap
>
cm
(
comp_map
,
num_vertices
(
g
),
hist
);
get_components
(
g
,
cm
,
typename
is_convertible
<
directed_category
,
directed_tag
>::
type
());
}
...
...
@@ -80,9 +151,10 @@ struct label_biconnected_components
template
<
class
Graph
,
class
CompMap
,
class
ArtMap
>
void
operator
()(
const
Graph
&
g
,
CompMap
comp_map
,
ArtMap
art_map
,
size_t
&
nc
)
const
vector
<
size_t
>
&
hist
)
const
{
nc
=
biconnected_components
(
g
,
comp_map
,
HistogramPropertyMap
<
CompMap
>
cm
(
comp_map
,
num_edges
(
g
),
hist
);
biconnected_components
(
g
,
cm
,
vertex_inserter
<
ArtMap
>
(
art_map
)).
first
;
}
};
...
...
src/graph_tool/topology/__init__.py
View file @
6b0e1705
...
...
@@ -50,11 +50,11 @@ from .. dl_import import dl_import
dl_import
(
"import libgraph_tool_topology"
)
from
..
import
_prop
,
Vector_int32_t
,
_check_prop_writable
,
\
_check_prop_scalar
,
_check_prop_vector
,
Graph
,
PropertyMap
_check_prop_scalar
,
_check_prop_vector
,
Graph
,
PropertyMap
,
GraphView
import
random
,
sys
,
numpy
,
weakref
__all__
=
[
"isomorphism"
,
"subgraph_isomorphism"
,
"mark_subgraph"
,
"min_spanning_tree"
,
"dominator_tree"
,
"topological_sort"
,
"transitive_closure"
,
"label_components"
,
"transitive_closure"
,
"label_components"
,
"label_largest_component"
,
"label_biconnected_components"
,
"shortest_distance"
,
"shortest_path"
,
"is_planar"
]
...
...
@@ -422,15 +422,16 @@ def label_components(g, vprop=None, directed=None):
Label the components to which each vertex in the graph belongs. If the
graph is directed, it finds the strongly connected components.
A property map with the component labels is returned, together with an
histogram of component labels.
Parameters
----------
g : :class:`~graph_tool.Graph`
Graph to be used.
vprop : :class:`~graph_tool.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.
...
...
@@ -439,6 +440,8 @@ def label_components(g, vprop=None, directed=None):
-------
comp : :class:`~graph_tool.PropertyMap`
Vertex property map with component labels.
hist : :class:`~numpy.ndarray`
Histogram of component labels.
Notes
-----
...
...
@@ -452,11 +455,13 @@ def label_components(g, vprop=None, directed=None):
>>> from numpy.random import seed
>>> seed(43)
>>> g = gt.random_graph(100, lambda: (1, 1))
>>> comp = gt.label_components(g)
>>> comp
, hist
= gt.label_components(g)
>>> print comp.get_array()
[0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 2 0 0 0 1 0 0 0 0 1 1 0 2 0 1 1 0 0 0 0 1 0
0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 2 0 0 0 0 1 0 0 0 0 0 1 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0]
>>> print hist
[81 15 4]
"""
if
vprop
is
None
:
...
...
@@ -465,17 +470,57 @@ def label_components(g, vprop=None, directed=None):
_check_prop_writable
(
vprop
,
name
=
"vprop"
)
_check_prop_scalar
(
vprop
,
name
=
"vprop"
)
try
:
if
directed
is
not
None
:
g
.
stash_filter
(
directed
=
True
)
g
.
set_directed
(
directed
)
g
=
GraphView
(
g
,
directed
=
directed
)
libgraph_tool_topology
.
\
hist
=
libgraph_tool_topology
.
\
label_components
(
g
.
_Graph__graph
,
_prop
(
"v"
,
g
,
vprop
))
finally
:
if
directed
is
not
None
:
g
.
pop_filter
(
directed
=
True
)
return
vprop
return
vprop
,
hist
def
label_largest_component
(
g
,
directed
=
None
):
"""
Label the largest component in the graph. If the graph is directed, it
labels the largest strongly connected components.
A property map with a boolean label is returned.
Parameters
----------
g : :class:`~graph_tool.Graph`
Graph to be used.
directed : bool (optional, default:None)
Treat graph as directed or not, independently of its actual
directionality.
Returns
-------
comp : :class:`~graph_tool.PropertyMap`
Vertex property map which labels the largest component with value 1.
Notes
-----
The algorithm runs in :math:`O(V + E)` time.
Examples
--------
>>> from numpy.random import seed, poisson
>>> seed(43)
>>> g = gt.random_graph(100, lambda: poisson(1), directed=False)
>>> l = gt.label_largest_component(g)
>>> print l.a
[1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0
0 0 1 1 0 0 1 0 0 1 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 1
0 0 0 0 1 0 0 1 0 1 1 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0]
>>> u = gt.GraphView(g, vfilt=l) # extract the largest component as a graph
>>> print u.num_vertices()
26
"""
label
=
g
.
new_vertex_property
(
"bool"
)
c
,
h
=
label_components
(
g
,
directed
=
directed
)
label
.
a
=
c
.
a
==
h
.
argmax
()
return
label
def
label_biconnected_components
(
g
,
eprop
=
None
,
vprop
=
None
):
...
...
@@ -483,6 +528,10 @@ def label_biconnected_components(g, eprop=None, vprop=None):
Label the edges of biconnected components, and the vertices which are
articulation points.
An edge property map with the component labels is returned, together a
boolean vertex map marking the articulation points, and an histogram of
component labels.
Parameters
----------
g : :class:`~graph_tool.Graph`
...
...
@@ -529,7 +578,7 @@ def label_biconnected_components(g, eprop=None, vprop=None):
>>> from numpy.random import seed
>>> seed(43)
>>> g = gt.random_graph(100, lambda: 2, directed=False)
>>> comp, art,
nc
= gt.label_biconnected_components(g)
>>> comp, art,
hist
= gt.label_biconnected_components(g)
>>> print comp.a
[1 0 0 0 2 0 1 0 0 0 0 0 1 0 0 3 0 0 0 0 0 0 0 0 2 0 0 0 0 0 1 1 0 0 0 0 0
1 0 1 3 0 2 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 3 0 0 0 0 0 0 0 0 0 1 0
...
...
@@ -538,8 +587,8 @@ def label_biconnected_components(g, eprop=None, vprop=None):
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
>>> print
nc
4
>>> print
hist
[77 13 6 4]
"""
...
...
@@ -553,15 +602,11 @@ def label_biconnected_components(g, eprop=None, vprop=None):
_check_prop_writable
(
eprop
,
name
=
"eprop"
)
_check_prop_scalar
(
eprop
,
name
=
"eprop"
)
g
.
stash_filter
(
directed
=
True
)
try
:
g
.
set_directed
(
False
)
nc
=
libgraph_tool_topology
.
\
g
=
GraphView
(
g
,
directed
=
False
)
hist
=
libgraph_tool_topology
.
\
label_biconnected_components
(
g
.
_Graph__graph
,
_prop
(
"e"
,
g
,
eprop
),
_prop
(
"v"
,
g
,
vprop
))
finally
:
g
.
pop_filter
(
directed
=
True
)
return
eprop
,
vprop
,
nc
return
eprop
,
vprop
,
hist
def
shortest_distance
(
g
,
source
=
None
,
weights
=
None
,
max_dist
=
None
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment