Skip to content
GitLab
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
1441551e
Commit
1441551e
authored
Nov 02, 2013
by
Tiago Peixoto
Browse files
Improve performance of global/local_clustering()
parent
4d7eb88e
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/graph/clustering/graph_clustering.hh
View file @
1441551e
...
...
@@ -18,10 +18,16 @@
#ifndef GRAPH_CLUSTERING_HH
#define GRAPH_CLUSTERING_HH
#include
"config.h"
#include
"tr1_include.hh"
#include TR1_HEADER(unordered_set)
#include
<boost/mpl/if.hpp>
#ifdef HAVE_SPARSEHASH
#include
<dense_hash_set>
#endif
#include
<ext/numeric>
using
__gnu_cxx
::
power
;
...
...
@@ -29,59 +35,53 @@ namespace graph_tool
{
using
namespace
boost
;
#ifdef HAVE_SPARSEHASH
using
google
::
dense_hash_set
;
#endif
// calculates the number of triangles to which v belongs
template
<
class
Graph
>
pair
<
int
,
int
>
get_triangles
(
typename
graph_traits
<
Graph
>::
vertex_descriptor
v
,
const
Graph
&
g
)
{
tr1
::
unordered_set
<
typename
graph_traits
<
Graph
>::
vertex_descriptor
>
neighbour_set1
,
neighbour_set2
,
neighbour_set3
;
typedef
typename
graph_traits
<
Graph
>::
vertex_descriptor
vertex_t
;
#ifdef HAVE_SPARSEHASH
typedef
dense_hash_set
<
vertex_t
>
set_t
;
#else
typedef
unordered_set
<
vertex_t
>
set_t
;
#endif
set_t
neighbour_set
;
#ifdef HAVE_SPARSEHASH
neighbour_set
.
set_empty_key
(
numeric_limits
<
vertex_t
>::
max
());
neighbour_set
.
resize
(
out_degree
(
v
,
g
));
#endif
size_t
triangles
=
0
,
k
=
0
;
size_t
triangles
=
0
;
typename
graph_traits
<
Graph
>::
adjacency_iterator
n1_begin
,
n1_end
,
n1
;
tie
(
n1_begin
,
n1_end
)
=
adjacent_vertices
(
v
,
g
);
for
(
n1
=
n1_begin
;
n1
!=
n1_end
;
++
n1
)
typename
graph_traits
<
Graph
>::
adjacency_iterator
n
,
n_end
;
for
(
tie
(
n
,
n_end
)
=
adjacent_vertices
(
v
,
g
);
n
!=
n_end
;
++
n
)
{
if
(
*
n
1
==
v
)
// no self-loops
if
(
*
n
==
v
)
// no self-loops
continue
;
if
(
neighbour_set1
.
find
(
*
n1
)
!=
neighbour_set1
.
end
())
continue
;
else
neighbour_set1
.
insert
(
*
n1
);
neighbour_set
.
insert
(
*
n
);
}
typename
graph_traits
<
Graph
>::
adjacency_iterator
n2_begin
,
n2_end
,
n2
;
tie
(
n2_begin
,
n2_end
)
=
adjacent_vertices
(
*
n1
,
g
);
for
(
n2
=
n2_begin
;
n2
!=
n2_end
;
++
n2
)
for
(
tie
(
n
,
n_end
)
=
adjacent_vertices
(
v
,
g
);
n
!=
n_end
;
++
n
)
{
typename
graph_traits
<
Graph
>::
adjacency_iterator
n2
,
n2_end
;
for
(
tie
(
n2
,
n2_end
)
=
adjacent_vertices
(
*
n
,
g
);
n2
!=
n2_end
;
++
n2
)
{
if
(
*
n2
==
*
n
1
)
// no self-loops
if
(
*
n2
==
*
n
)
// no self-loops
continue
;
if
(
neighbour_set2
.
find
(
*
n2
)
!=
neighbour_set2
.
end
())
continue
;
else
neighbour_set2
.
insert
(
*
n2
);
typename
graph_traits
<
Graph
>::
adjacency_iterator
n3_begin
,
n3_end
,
n3
;
tie
(
n3_begin
,
n3_end
)
=
adjacent_vertices
(
*
n2
,
g
);
for
(
n3
=
n3_begin
;
n3
!=
n3_end
;
++
n3
)
{
if
(
*
n3
==
*
n2
)
// no self-loops
continue
;
if
(
neighbour_set3
.
find
(
*
n3
)
!=
neighbour_set3
.
end
())
continue
;
else
neighbour_set3
.
insert
(
*
n3
);
if
(
*
n3
==
v
)
//found a triangle
triangles
++
;
}
neighbour_set3
.
clear
();
if
(
neighbour_set
.
find
(
*
n2
)
!=
neighbour_set
.
end
())
++
triangles
;
}
neighbour_set2
.
clear
();
k
++
;
}
neighbour_set1
.
clear
();
size_t
k
=
out_degree
(
v
,
g
);
return
make_pair
(
triangles
/
2
,(
k
*
(
k
-
1
))
/
2
);
}
...
...
@@ -113,8 +113,7 @@ struct get_global_clustering
// "jackknife" variance
c_err
=
0.0
;
double
cerr
=
0.0
;
double
cerr
=
0.0
;
#pragma omp parallel for default(shared) private(i,temp) \
schedule(static) if (N > 100) reduction(+:cerr)
...
...
@@ -155,10 +154,7 @@ struct set_clustering_to_property
double
(
triangles
.
first
)
/
triangles
.
second
:
0.0
;
#pragma omp critical
{
clust_map
[
v
]
=
c_type
(
clustering
);
}
clust_map
[
v
]
=
c_type
(
clustering
);
}
}
...
...
src/graph_tool/clustering/__init__.py
View file @
1441551e
...
...
@@ -134,7 +134,7 @@ def local_clustering(g, prop=None, undirected=True):
prop
=
g
.
new_vertex_property
(
"double"
)
if
g
.
is_directed
()
and
undirected
:
g
=
GraphView
(
g
,
directed
=
False
)
_gt
.
extended
_clustering
(
g
.
_Graph__graph
,
[
_prop
(
"v"
,
g
,
prop
)
]
)
_gt
.
local
_clustering
(
g
.
_Graph__graph
,
_prop
(
"v"
,
g
,
prop
))
return
prop
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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