Skip to content

Commit 385c85b

Browse files
authored
Katz Centrality, Docs, Examples (#19)
1 parent 9d4886c commit 385c85b

File tree

7 files changed

+606
-41
lines changed

7 files changed

+606
-41
lines changed

examples/centrality.rs

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
//
2+
// -----------------------------
3+
// Degree Centrality
4+
// -----------------------------
5+
//
6+
7+
fn degree_centrality_example() {
8+
use graphina::core::types::Graph;
9+
10+
use graphina::centrality::algorithms::degree_centrality;
11+
12+
let mut g: Graph<i32, ()> = Graph::new();
13+
let nodes = [g.add_node(1), g.add_node(2), g.add_node(3)];
14+
g.add_edge(nodes[0], nodes[1], ());
15+
g.add_edge(nodes[0], nodes[2], ());
16+
17+
let centrality = degree_centrality(&g);
18+
println!("{:?}", centrality); // [2.0, 1.0, 1.0]
19+
}
20+
21+
fn in_degree_centrality_example() {
22+
use graphina::core::types::Digraph;
23+
24+
use graphina::centrality::algorithms::in_degree_centrality;
25+
26+
let mut g: Digraph<i32, ()> = Digraph::new();
27+
let nodes = [g.add_node(1), g.add_node(2), g.add_node(3)];
28+
g.add_edge(nodes[0], nodes[1], ());
29+
g.add_edge(nodes[0], nodes[2], ());
30+
31+
let centrality = in_degree_centrality(&g);
32+
println!("{:?}", centrality); // [0.0, 1.0, 1.0]
33+
}
34+
35+
fn out_degree_centrality_example() {
36+
use graphina::core::types::Digraph;
37+
38+
use graphina::centrality::algorithms::out_degree_centrality;
39+
40+
let mut g: Digraph<i32, ()> = Digraph::new();
41+
let nodes = [g.add_node(1), g.add_node(2), g.add_node(3)];
42+
g.add_edge(nodes[0], nodes[1], ());
43+
g.add_edge(nodes[0], nodes[2], ());
44+
45+
let centrality = out_degree_centrality(&g);
46+
println!("{:?}", centrality); // [2.0, 0.0, 0.0]
47+
}
48+
49+
//
50+
// -----------------------------
51+
// Eigen Vector Centrality
52+
// -----------------------------
53+
//
54+
55+
fn eigenvector_centrality_example() {
56+
use graphina::core::types::Graph;
57+
58+
use graphina::centrality::algorithms::eigenvector_centrality;
59+
60+
let mut g = Graph::new();
61+
let nodes = [g.add_node(1), g.add_node(2), g.add_node(3)];
62+
g.add_edge(nodes[0], nodes[1], 1.0);
63+
g.add_edge(nodes[0], nodes[2], 2.0);
64+
65+
let centrality = eigenvector_centrality(&g, 1000, false);
66+
println!("{:.5?}", centrality); // [0.70711, 0.50000, 0.50000]
67+
let centrality = eigenvector_centrality(&g, 1000, true);
68+
println!("{:.5?}", centrality); // [0.70711, 0.31623, 0.63246]
69+
}
70+
71+
fn eigenvector_centrality_numpy_example() {
72+
use graphina::centrality::algorithms::eigenvector_centrality_numpy;
73+
use graphina::core::types::Graph;
74+
let mut g = Graph::new();
75+
76+
let nodes = [g.add_node(1), g.add_node(2), g.add_node(3)];
77+
g.add_edge(nodes[0], nodes[1], 1.0);
78+
g.add_edge(nodes[0], nodes[2], 2.0);
79+
80+
let centrality = eigenvector_centrality_numpy(&g, 1000, 1e-6_f64, false);
81+
println!("{:.5?}", centrality); // [0.70711, 0.50000, 0.50000]
82+
let centrality = eigenvector_centrality_numpy(&g, 1000, 1e-6_f64, true);
83+
println!("{:.5?}", centrality); // [0.70711, 0.31623, 0.63246]
84+
}
85+
86+
fn eigenvector_centrality_impl_example() {
87+
use graphina::centrality::algorithms::eigenvector_centrality_impl;
88+
use graphina::core::types::Graph;
89+
90+
let mut g: Graph<i32, (f64, f64)> = Graph::new();
91+
// ^^^^^^^^^^
92+
// L arbitrary type as edge
93+
let nodes = [g.add_node(1), g.add_node(2), g.add_node(3)];
94+
g.add_edge(nodes[0], nodes[1], (0.0, 1.0));
95+
g.add_edge(nodes[0], nodes[2], (1.0, 0.0));
96+
let centrality = eigenvector_centrality_impl(
97+
&g,
98+
1000,
99+
1e-6_f64,
100+
|w| w.0 * 10.0 + w.1, // <-- custom evaluation for edge weight
101+
);
102+
println!("{:.5?}", centrality); // [0.70711, 0.07036, 0.70360]
103+
}
104+
105+
//
106+
// -----------------------------
107+
// Katz Centrality
108+
// -----------------------------
109+
//
110+
111+
fn katz_centrality_example() {
112+
use graphina::centrality::algorithms::katz_centrality;
113+
use graphina::core::types::Graph;
114+
115+
let mut g = Graph::new();
116+
let nodes = [g.add_node(1), g.add_node(2), g.add_node(3)];
117+
g.add_edge(nodes[0], nodes[1], 1.0);
118+
g.add_edge(nodes[0], nodes[2], 2.0);
119+
120+
let centrality = katz_centrality(&g, 0.1, 1.0, 1000, false, true);
121+
println!("{:.5?}", centrality); // [0.61078, 0.55989, 0.55989]
122+
let centrality = katz_centrality(&g, 0.01, 0.5, 1000, true, true);
123+
println!("{:.5?}", centrality); // [0.58301, 0.57158, 0.57741]
124+
}
125+
126+
fn katz_centrality_numpy_example() {
127+
use graphina::centrality::algorithms::katz_centrality_numpy;
128+
use graphina::core::types::Graph;
129+
130+
let mut g = Graph::new();
131+
let nodes = [g.add_node(1), g.add_node(2), g.add_node(3)];
132+
g.add_edge(nodes[0], nodes[1], 1.0);
133+
g.add_edge(nodes[0], nodes[2], 2.0);
134+
135+
let centrality = katz_centrality_numpy(&g, 0.1, 1.0, false, true);
136+
println!("{:.5?}", centrality); // [0.61078, 0.55989, 0.55989]
137+
let centrality = katz_centrality_numpy(&g, 0.01, 0.5, true, true);
138+
println!("{:.5?}", centrality); // [0.58301, 0.57158, 0.57741]
139+
}
140+
141+
fn katz_centrality_impl_example() {
142+
use graphina::centrality::algorithms::katz_centrality_impl;
143+
use graphina::core::types::Graph;
144+
145+
let mut g: Graph<(i32, f64), (f64, f64)> = Graph::new();
146+
// ^^^^^^^^^^ ^^^^^^^^^^
147+
// | L arbitrary type as edge
148+
// L arbitrary type as node
149+
let nodes = [
150+
g.add_node((1, 2.0)),
151+
g.add_node((2, 3.0)),
152+
g.add_node((3, 2.0)),
153+
];
154+
g.add_edge(nodes[0], nodes[1], (0.0, 1.0));
155+
g.add_edge(nodes[0], nodes[2], (1.0, 0.0));
156+
157+
let centrality = katz_centrality_impl(
158+
&g,
159+
|_n| 0.01, // <-- custom alpha depend on node attribute
160+
|(i, f): &(i32, f64)| f.powi(*i), // <-- custom beta depend on node attribute
161+
1_000,
162+
1e-6_f64,
163+
true,
164+
|w| w.0 * 10.0 + w.1, // <-- custom evaluation for edge weight
165+
);
166+
println!("{:.5?}", centrality); // [0.23167, 0.71650, 0.65800]
167+
}
168+
169+
macro_rules! run_examples {
170+
($($func:ident),* $(,)?) => {
171+
$(
172+
println!("<{}>", stringify!($func));
173+
$func();
174+
println!();
175+
)*
176+
};
177+
}
178+
179+
fn main() {
180+
run_examples!(
181+
// degree centrality
182+
degree_centrality_example,
183+
in_degree_centrality_example,
184+
out_degree_centrality_example,
185+
// eigen vector centrality
186+
eigenvector_centrality_example,
187+
eigenvector_centrality_numpy_example,
188+
eigenvector_centrality_impl_example,
189+
// katz centrality
190+
katz_centrality_example,
191+
katz_centrality_numpy_example,
192+
katz_centrality_impl_example
193+
);
194+
}

examples/centrality_eigenvector.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import networkx as nx
2+
3+
G = nx.Graph()
4+
5+
for i in range(5):
6+
G.add_node(i)
7+
8+
edges = [
9+
(0, 1, 1.0),
10+
(0, 2, 2.0),
11+
(1, 3, 1.0),
12+
]
13+
14+
for src, dst, weight in edges:
15+
G.add_edge(src, dst, weight=weight)
16+
17+
centrality = nx.eigenvector_centrality(G, weight=None)
18+
print("Unweighted: ")
19+
for v, c in centrality.items():
20+
print(f">> {v} : {c:.5f}")
21+
centrality = nx.eigenvector_centrality(G, weight="weight")
22+
print("Weighted: ")
23+
for v, c in centrality.items():
24+
print(f">> {v} : {c:.5f}")

examples/centrality_eigenvector.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use graphina::core::types::Graph;
2+
3+
use graphina::centrality::algorithms::eigenvector_centrality;
4+
5+
fn main() {
6+
let mut graph = Graph::new();
7+
let ids = (0..5).map(|i| graph.add_node(i)).collect::<Vec<_>>();
8+
let edges = [(0, 1, 1.0), (0, 2, 2.0), (1, 3, 1.0)];
9+
for (s, d, w) in edges {
10+
graph.add_edge(ids[s], ids[d], w);
11+
}
12+
13+
let centrality = eigenvector_centrality(&graph, 1000, false);
14+
println!("Unweighted",);
15+
for (n, attr) in graph.nodes() {
16+
println!(">> {} : {:.5}", attr, centrality[n.index()])
17+
}
18+
println!();
19+
let centrality = eigenvector_centrality(&graph, 1000, true);
20+
println!("Weighted",);
21+
for (n, attr) in graph.nodes() {
22+
println!(">> {} : {:.5}", attr, centrality[n.index()])
23+
}
24+
println!();
25+
}

examples/centrality_katz.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import networkx as nx
2+
3+
G = nx.DiGraph()
4+
5+
for i in range(5):
6+
G.add_node(i)
7+
8+
edges = [
9+
(0, 1, 1.0),
10+
(0, 2, 2.0),
11+
(1, 3, 1.0),
12+
]
13+
14+
for src, dst, weight in edges:
15+
G.add_edge(src, dst, weight=weight)
16+
17+
params = [
18+
(0.1, 1.0, 1000, None, True),
19+
(0.1, 1.0, 1000, None, False),
20+
(0.01, 0.5, 1000, "weight", False),
21+
(0.01, 0.5, 1000, "weight", True),
22+
]
23+
24+
for alpha, beta, max_iter, weight, normalized in params:
25+
centrality = nx.katz_centrality(
26+
G,
27+
alpha=alpha,
28+
beta=beta,
29+
max_iter=max_iter,
30+
weight=weight,
31+
normalized=normalized,
32+
)
33+
34+
print(f"alpha: {alpha:.3f}, beta: {beta:.3f}, max iter: {max_iter:>5}, ", end="")
35+
print(f"weighted: {weight=='weight'}, normalized: {normalized}".lower())
36+
for k, v in centrality.items():
37+
print(f">> {k} : {v:>.5f}")
38+
print()

examples/centrality_katz.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use graphina::core::types::Digraph;
2+
3+
use graphina::centrality::algorithms::katz_centrality;
4+
5+
fn main() {
6+
let mut graph = Digraph::new();
7+
let ids = (0..5).map(|i| graph.add_node(i)).collect::<Vec<_>>();
8+
let edges = [(0, 1, 1.0), (0, 2, 2.0), (1, 3, 1.0)];
9+
for (s, d, w) in edges {
10+
graph.add_edge(ids[s], ids[d], w);
11+
}
12+
13+
let params = [
14+
(0.1, 1.0, 1000, false, true),
15+
(0.1, 1.0, 1000, false, false),
16+
(0.01, 0.5, 1000, true, false),
17+
(0.01, 0.5, 1000, true, true),
18+
];
19+
20+
for (alpha, beta, max_iter, weighted, normalized) in params {
21+
let centrality = katz_centrality(&graph, alpha, beta, max_iter, weighted, normalized);
22+
println!(
23+
"alpha: {:.3}, beta: {:.3}, max iter: {:>5}, weighted: {}, normalized: {}",
24+
alpha, beta, max_iter, weighted, normalized
25+
);
26+
for (n, attr) in graph.nodes() {
27+
println!(">> {} : {:.5}", attr, centrality[n.index()])
28+
}
29+
println!();
30+
}
31+
}

0 commit comments

Comments
 (0)