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
95470ff4
Commit
95470ff4
authored
Aug 24, 2011
by
Tiago Peixoto
Browse files
Implement eigenvector centrality
parent
ef9ad955
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/graph/centrality/Makefile.am
View file @
95470ff4
...
...
@@ -16,13 +16,15 @@ libgraph_tool_centrality_la_LDFLAGS = $(MOD_LDFLAGS)
libgraph_tool_centrality_la_SOURCES
=
\
graph_betweenness.cc
\
graph_
pagerank
.cc
\
graph_
centrality_bind
.cc
\
graph_eigentrust.cc
\
graph_trust_transitivity.cc
\
graph_centrality_bind.cc
graph_eigenvector.cc
\
graph_pagerank.cc
\
graph_trust_transitivity.cc
libgraph_tool_centrality_la_include_HEADERS
=
\
graph_pagerank.hh
\
graph_eigentrust.hh
\
graph_eigenvector.hh
\
graph_pagerank.hh
\
graph_trust_transitivity.hh
\
minmax.hh
src/graph/centrality/graph_centrality_bind.cc
View file @
95470ff4
...
...
@@ -21,6 +21,7 @@ using namespace boost;
void
export_betweenness
();
void
export_eigentrust
();
void
export_eigenvector
();
void
export_trust_transitivity
();
void
export_pagerank
();
...
...
@@ -28,6 +29,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_centrality)
{
export_betweenness
();
export_eigentrust
();
export_eigenvector
();
export_trust_transitivity
();
export_pagerank
();
}
src/graph/centrality/graph_eigenvector.cc
0 → 100644
View file @
95470ff4
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007-2011 Tiago de Paula Peixoto <tiago@skewed.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
<boost/python.hpp>
#include
"graph.hh"
#include
"graph_selectors.hh"
#include
"graph_eigenvector.hh"
using
namespace
std
;
using
namespace
boost
;
using
namespace
graph_tool
;
long
double
eigenvector
(
GraphInterface
&
g
,
boost
::
any
w
,
boost
::
any
c
,
double
epsilon
,
size_t
max_iter
)
{
if
(
!
w
.
empty
()
&&
!
belongs
<
writable_edge_scalar_properties
>
()(
w
))
throw
ValueException
(
"edge property must be writable"
);
if
(
!
belongs
<
vertex_floating_properties
>
()(
c
))
throw
ValueException
(
"vertex property must be of floating point"
" value type"
);
typedef
ConstantPropertyMap
<
int
,
GraphInterface
::
vertex_t
>
weight_map_t
;
typedef
mpl
::
push_back
<
writable_edge_scalar_properties
,
weight_map_t
>::
type
weight_props_t
;
if
(
w
.
empty
())
w
=
weight_map_t
(
1
);
long
double
eig
=
0
;
run_action
<>
()
(
g
,
bind
<
void
>
(
get_eigenvector
(),
_1
,
g
.
GetVertexIndex
(),
g
.
GetEdgeIndex
(),
_2
,
_3
,
epsilon
,
max_iter
,
ref
(
eig
)),
writable_edge_scalar_properties
(),
vertex_floating_properties
())(
w
,
c
);
return
eig
;
}
void
export_eigenvector
()
{
using
namespace
boost
::
python
;
def
(
"get_eigenvector"
,
&
eigenvector
);
}
src/graph/centrality/graph_eigenvector.hh
0 → 100644
View file @
95470ff4
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007-2011 Tiago de Paula Peixoto <tiago@skewed.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_EIGENVECTOR_HH
#define GRAPH_EIGENVECTOR_HH
#include
"graph.hh"
#include
"graph_filtering.hh"
#include
"graph_util.hh"
#include
<ext/numeric>
using
__gnu_cxx
::
power
;
namespace
graph_tool
{
using
namespace
std
;
using
namespace
boost
;
struct
get_eigenvector
{
template
<
class
Graph
,
class
VertexIndex
,
class
EdgeIndex
,
class
WeightMap
,
class
CentralityMap
>
void
operator
()(
Graph
&
g
,
VertexIndex
vertex_index
,
EdgeIndex
edge_index
,
WeightMap
w
,
CentralityMap
c
,
double
epsilon
,
size_t
max_iter
,
long
double
&
eig
)
const
{
typedef
typename
property_traits
<
WeightMap
>::
value_type
c_type
;
typedef
typename
property_traits
<
CentralityMap
>::
value_type
t_type
;
CentralityMap
c_temp
(
vertex_index
,
num_vertices
(
g
));
// init centrality
int
i
,
N
=
num_vertices
(
g
),
V
=
HardNumVertices
()(
g
);
#pragma omp parallel for default(shared) private(i) \
schedule(dynamic)
for
(
i
=
0
;
i
<
N
;
++
i
)
{
typename
graph_traits
<
Graph
>::
vertex_descriptor
v
=
vertex
(
i
,
g
);
if
(
v
==
graph_traits
<
Graph
>::
null_vertex
())
continue
;
c
[
v
]
=
1.0
/
V
;
}
t_type
norm
=
0
;
t_type
delta
=
epsilon
+
1
;
size_t
iter
=
0
;
while
(
delta
>=
epsilon
)
{
norm
=
0
;
int
i
,
N
=
num_vertices
(
g
);
#pragma omp parallel for default(shared) private(i) \
schedule(dynamic) reduction(+:norm)
for
(
i
=
0
;
i
<
N
;
++
i
)
{
typename
graph_traits
<
Graph
>::
vertex_descriptor
v
=
vertex
(
i
,
g
);
if
(
v
==
graph_traits
<
Graph
>::
null_vertex
())
continue
;
c_temp
[
v
]
=
0
;
typename
in_edge_iteratorS
<
Graph
>::
type
e
,
e_end
;
for
(
tie
(
e
,
e_end
)
=
in_edge_iteratorS
<
Graph
>::
get_edges
(
v
,
g
);
e
!=
e_end
;
++
e
)
{
typename
graph_traits
<
Graph
>::
vertex_descriptor
s
=
source
(
*
e
,
g
);
c_temp
[
v
]
+=
get
(
w
,
*
e
)
*
c
[
s
];
}
norm
+=
power
(
c_temp
[
v
],
2
);
}
norm
=
sqrt
(
norm
);
delta
=
0
;
#pragma omp parallel for default(shared) private(i) \
schedule(dynamic) reduction(+:delta)
for
(
i
=
0
;
i
<
N
;
++
i
)
{
typename
graph_traits
<
Graph
>::
vertex_descriptor
v
=
vertex
(
i
,
g
);
if
(
v
==
graph_traits
<
Graph
>::
null_vertex
())
continue
;
c_temp
[
v
]
/=
norm
;
delta
+=
abs
(
c_temp
[
v
]
-
c
[
v
]);
}
swap
(
c_temp
,
c
);
++
iter
;
if
(
max_iter
>
0
&&
iter
==
max_iter
)
break
;
}
if
(
iter
%
2
!=
0
)
{
#pragma omp parallel for default(shared) private(i) \
schedule(dynamic)
for
(
int
i
=
0
;
i
<
N
;
++
i
)
{
typename
graph_traits
<
Graph
>::
vertex_descriptor
v
=
vertex
(
i
,
g
);
if
(
v
==
graph_traits
<
Graph
>::
null_vertex
())
continue
;
c
[
v
]
=
c_temp
[
v
];
}
}
eig
=
1.
/
norm
;
}
};
}
#endif
src/graph_tool/centrality/__init__.py
View file @
95470ff4
...
...
@@ -33,6 +33,7 @@ Summary
pagerank
betweenness
central_point_dominance
eigenvector
eigentrust
trust_transitivity
...
...
@@ -48,7 +49,7 @@ import sys
import
numpy
__all__
=
[
"pagerank"
,
"betweenness"
,
"central_point_dominance"
,
"eigentrust"
,
"trust_transitivity"
]
"eigenvector"
,
"trust_transitivity"
]
def
pagerank
(
g
,
damping
=
0.85
,
pers
=
None
,
weight
=
None
,
prop
=
None
,
epsilon
=
1e-6
,
...
...
@@ -362,6 +363,112 @@ def central_point_dominance(g, betweenness):
_prop
(
"v"
,
g
,
betweenness
))
def
eigenvector
(
g
,
weight
=
None
,
vprop
=
None
,
epsilon
=
1e-6
,
max_iter
=
None
):
r
"""
Calculate the eigenvector centrality of each vertex in the graph, as well as
the largest eigenvalue.
Parameters
----------
g : :class:`~graph_tool.Graph`
Graph to be used.
weights : :class:`~graph_tool.PropertyMap` (optional, default: ``None``)
Edge property map with the edge weights.
vprop : :class:`~graph_tool.PropertyMap`, optional (default: ``None``)
Vertex property map where the values of eigenvector must be stored.
epsilon : float, optional (default: ``1e-6``)
Convergence condition. The iteration will stop if the total delta of all
vertices are below this value.
max_iter : int, optional (default: ``None``)
If supplied, this will limit the total number of iterations.
Returns
-------
eigenvalue : float
The largest eigenvalue of the (weighted) adjacency matrix.
eigenvector : :class:`~graph_tool.PropertyMap`
A vertex property map containing the eigenvector values.
See Also
--------
betweenness: betweenness centrality
pagerank: PageRank centrality
trust_transitivity: pervasive trust transitivity
Notes
-----
The eigenvector centrality :math:`\mathbf{x}` is the eigenvector of the
(weighted) adjacency matrix with the largest eigenvalue :math:`\lambda`,
i.e. it is the solution of
.. math::
\mathbf{A}\mathbf{x} = \lambda\mathbf{x},
where :math:`\mathbf{A}` is the (weighted) adjacency matrix and
:math:`\lambda` is the largest eigenvalue.
The algorithm uses the power method which has a topology-dependent complexity of
:math:`O\left(N\times\frac{-\log\epsilon}{\log|\lambda_1/\lambda_2|}\right)`,
where :math:`N` is the number of vertices, :math:`\epsilon` is the ``epsilon``
parameter, and :math:`\lambda_1` and :math:`\lambda_2` are the largest and
second largest eigenvalues of the (weighted) adjacency matrix, respectively.
If enabled during compilation, this algorithm runs in parallel.
Examples
--------
>>> from numpy.random import poisson, random, seed
>>> seed(42)
>>> g = gt.random_graph(100, lambda: (poisson(3), poisson(3)))
>>> w = g.new_edge_property("double")
>>> w.a = random(g.num_edges()) * 42
>>> x = gt.eigenvector(g, w)
>>> print x[0]
0.0160851991895
>>> print x[1].a
[ 0.1376411 0.07207366 0.02727508 0.05805304 0. 0.10690994
0.04315491 0.01040908 0.02300252 0.08874163 0.04968119 0.06718114
0.05526028 0.20449371 0.02337425 0.07581173 0.19993899 0.14718912
0.08464664 0.08474977 0. 0.04843894 0. 0.0089388
0.16831573 0.00138653 0.11741616 0. 0.13455019 0.03642682
0.06729803 0.06229526 0.08937098 0.05693976 0.0793375 0.04076743
0.22176891 0.07717256 0.00518048 0.05722748 0. 0.00055799
0.04541778 0.06420469 0.06189998 0.08011859 0.05377224 0.29979873
0.01211309 0.15503588 0.02804072 0.1692873 0.01420732 0.02507
0.02959899 0.02702304 0.1652933 0.01434992 0.1073001 0.04582697
0.04618913 0.0220902 0.01421926 0.09891276 0.04522928 0.
0.00236599 0.07686829 0.03243909 0.00346715 0.1954776 0.
0.25583217 0.11710921 0.07804282 0.21188464 0.04800656 0.00321866
0.0552824 0.11204116 0.11420818 0.24071304 0.15451676 0.
0.00475456 0.10680434 0.17054333 0.18945499 0.15673649 0.03405238
0.01653319 0.02563015 0.00186129 0.12061027 0.11449362 0.11114196
0.06779788 0.00595725 0.09127559 0.02380386]
References
----------
.. [eigenvector-centrality] http://en.wikipedia.org/wiki/Centrality#Eigenvector_centrality
.. [power-method] http://en.wikipedia.org/wiki/Power_iteration
.. [langville-survey-2005] A. N. Langville, C. D. Meyer, "A Survey of
Eigenvector Methods for Web Information Retrieval", SIAM Review, vol. 47,
no. 1, pp. 135-161, 2005, :DOI:`10.1137/S0036144503424786`
"""
if
vprop
==
None
:
vprop
=
g
.
new_vertex_property
(
"double"
)
if
max_iter
is
None
:
max_iter
=
0
ee
=
libgraph_tool_centrality
.
\
get_eigenvector
(
g
.
_Graph__graph
,
_prop
(
"e"
,
g
,
weight
),
_prop
(
"v"
,
g
,
vprop
),
epsilon
,
max_iter
)
return
ee
,
vprop
def
eigentrust
(
g
,
trust_map
,
vprop
=
None
,
norm
=
False
,
epsilon
=
1e-6
,
max_iter
=
0
,
ret_iter
=
False
):
r
"""
...
...
Tiago Peixoto
@count0
mentioned in issue
#34 (closed)
·
Aug 06, 2014
mentioned in issue
#34 (closed)
mentioned in issue #34
Toggle commit list
Write
Preview
Supports
Markdown
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