Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,657 @@
|
|||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
def weighted_G():
|
||||
G = nx.Graph()
|
||||
G.add_edge(0, 1, weight=3)
|
||||
G.add_edge(0, 2, weight=2)
|
||||
G.add_edge(0, 3, weight=6)
|
||||
G.add_edge(0, 4, weight=4)
|
||||
G.add_edge(1, 3, weight=5)
|
||||
G.add_edge(1, 5, weight=5)
|
||||
G.add_edge(2, 4, weight=1)
|
||||
G.add_edge(3, 4, weight=2)
|
||||
G.add_edge(3, 5, weight=1)
|
||||
G.add_edge(4, 5, weight=4)
|
||||
return G
|
||||
|
||||
|
||||
class TestBetweennessCentrality:
|
||||
def test_K5(self):
|
||||
"""Betweenness centrality: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=False)
|
||||
b_answer = {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_K5_endpoints(self):
|
||||
"""Betweenness centrality: K5 endpoints"""
|
||||
G = nx.complete_graph(5)
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=False, endpoints=True)
|
||||
b_answer = {0: 4.0, 1: 4.0, 2: 4.0, 3: 4.0, 4: 4.0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
# normalized = True case
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=True, endpoints=True)
|
||||
b_answer = {0: 0.4, 1: 0.4, 2: 0.4, 3: 0.4, 4: 0.4}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P3_normalized(self):
|
||||
"""Betweenness centrality: P3 normalized"""
|
||||
G = nx.path_graph(3)
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=True)
|
||||
b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P3(self):
|
||||
"""Betweenness centrality: P3"""
|
||||
G = nx.path_graph(3)
|
||||
b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=False)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_sample_from_P3(self):
|
||||
G = nx.path_graph(3)
|
||||
b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
|
||||
b = nx.betweenness_centrality(G, k=3, weight=None, normalized=False, seed=1)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
b = nx.betweenness_centrality(G, k=2, weight=None, normalized=False, seed=1)
|
||||
# python versions give different results with same seed
|
||||
b_approx1 = {0: 0.0, 1: 1.5, 2: 0.0}
|
||||
b_approx2 = {0: 0.0, 1: 0.75, 2: 0.0}
|
||||
for n in sorted(G):
|
||||
assert b[n] in (b_approx1[n], b_approx2[n])
|
||||
|
||||
def test_P3_endpoints(self):
|
||||
"""Betweenness centrality: P3 endpoints"""
|
||||
G = nx.path_graph(3)
|
||||
b_answer = {0: 2.0, 1: 3.0, 2: 2.0}
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=False, endpoints=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
# normalized = True case
|
||||
b_answer = {0: 2 / 3, 1: 1.0, 2: 2 / 3}
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=True, endpoints=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_krackhardt_kite_graph(self):
|
||||
"""Betweenness centrality: Krackhardt kite graph"""
|
||||
G = nx.krackhardt_kite_graph()
|
||||
b_answer = {
|
||||
0: 1.667,
|
||||
1: 1.667,
|
||||
2: 0.000,
|
||||
3: 7.333,
|
||||
4: 0.000,
|
||||
5: 16.667,
|
||||
6: 16.667,
|
||||
7: 28.000,
|
||||
8: 16.000,
|
||||
9: 0.000,
|
||||
}
|
||||
for b in b_answer:
|
||||
b_answer[b] /= 2
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=False)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_krackhardt_kite_graph_normalized(self):
|
||||
"""Betweenness centrality: Krackhardt kite graph normalized"""
|
||||
G = nx.krackhardt_kite_graph()
|
||||
b_answer = {
|
||||
0: 0.023,
|
||||
1: 0.023,
|
||||
2: 0.000,
|
||||
3: 0.102,
|
||||
4: 0.000,
|
||||
5: 0.231,
|
||||
6: 0.231,
|
||||
7: 0.389,
|
||||
8: 0.222,
|
||||
9: 0.000,
|
||||
}
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_florentine_families_graph(self):
|
||||
"""Betweenness centrality: Florentine families graph"""
|
||||
G = nx.florentine_families_graph()
|
||||
b_answer = {
|
||||
"Acciaiuoli": 0.000,
|
||||
"Albizzi": 0.212,
|
||||
"Barbadori": 0.093,
|
||||
"Bischeri": 0.104,
|
||||
"Castellani": 0.055,
|
||||
"Ginori": 0.000,
|
||||
"Guadagni": 0.255,
|
||||
"Lamberteschi": 0.000,
|
||||
"Medici": 0.522,
|
||||
"Pazzi": 0.000,
|
||||
"Peruzzi": 0.022,
|
||||
"Ridolfi": 0.114,
|
||||
"Salviati": 0.143,
|
||||
"Strozzi": 0.103,
|
||||
"Tornabuoni": 0.092,
|
||||
}
|
||||
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_les_miserables_graph(self):
|
||||
"""Betweenness centrality: Les Miserables graph"""
|
||||
G = nx.les_miserables_graph()
|
||||
b_answer = {
|
||||
"Napoleon": 0.000,
|
||||
"Myriel": 0.177,
|
||||
"MlleBaptistine": 0.000,
|
||||
"MmeMagloire": 0.000,
|
||||
"CountessDeLo": 0.000,
|
||||
"Geborand": 0.000,
|
||||
"Champtercier": 0.000,
|
||||
"Cravatte": 0.000,
|
||||
"Count": 0.000,
|
||||
"OldMan": 0.000,
|
||||
"Valjean": 0.570,
|
||||
"Labarre": 0.000,
|
||||
"Marguerite": 0.000,
|
||||
"MmeDeR": 0.000,
|
||||
"Isabeau": 0.000,
|
||||
"Gervais": 0.000,
|
||||
"Listolier": 0.000,
|
||||
"Tholomyes": 0.041,
|
||||
"Fameuil": 0.000,
|
||||
"Blacheville": 0.000,
|
||||
"Favourite": 0.000,
|
||||
"Dahlia": 0.000,
|
||||
"Zephine": 0.000,
|
||||
"Fantine": 0.130,
|
||||
"MmeThenardier": 0.029,
|
||||
"Thenardier": 0.075,
|
||||
"Cosette": 0.024,
|
||||
"Javert": 0.054,
|
||||
"Fauchelevent": 0.026,
|
||||
"Bamatabois": 0.008,
|
||||
"Perpetue": 0.000,
|
||||
"Simplice": 0.009,
|
||||
"Scaufflaire": 0.000,
|
||||
"Woman1": 0.000,
|
||||
"Judge": 0.000,
|
||||
"Champmathieu": 0.000,
|
||||
"Brevet": 0.000,
|
||||
"Chenildieu": 0.000,
|
||||
"Cochepaille": 0.000,
|
||||
"Pontmercy": 0.007,
|
||||
"Boulatruelle": 0.000,
|
||||
"Eponine": 0.011,
|
||||
"Anzelma": 0.000,
|
||||
"Woman2": 0.000,
|
||||
"MotherInnocent": 0.000,
|
||||
"Gribier": 0.000,
|
||||
"MmeBurgon": 0.026,
|
||||
"Jondrette": 0.000,
|
||||
"Gavroche": 0.165,
|
||||
"Gillenormand": 0.020,
|
||||
"Magnon": 0.000,
|
||||
"MlleGillenormand": 0.048,
|
||||
"MmePontmercy": 0.000,
|
||||
"MlleVaubois": 0.000,
|
||||
"LtGillenormand": 0.000,
|
||||
"Marius": 0.132,
|
||||
"BaronessT": 0.000,
|
||||
"Mabeuf": 0.028,
|
||||
"Enjolras": 0.043,
|
||||
"Combeferre": 0.001,
|
||||
"Prouvaire": 0.000,
|
||||
"Feuilly": 0.001,
|
||||
"Courfeyrac": 0.005,
|
||||
"Bahorel": 0.002,
|
||||
"Bossuet": 0.031,
|
||||
"Joly": 0.002,
|
||||
"Grantaire": 0.000,
|
||||
"MotherPlutarch": 0.000,
|
||||
"Gueulemer": 0.005,
|
||||
"Babet": 0.005,
|
||||
"Claquesous": 0.005,
|
||||
"Montparnasse": 0.004,
|
||||
"Toussaint": 0.000,
|
||||
"Child1": 0.000,
|
||||
"Child2": 0.000,
|
||||
"Brujon": 0.000,
|
||||
"MmeHucheloup": 0.000,
|
||||
}
|
||||
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_ladder_graph(self):
|
||||
"""Betweenness centrality: Ladder graph"""
|
||||
G = nx.Graph() # ladder_graph(3)
|
||||
G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (4, 5), (3, 5)])
|
||||
b_answer = {0: 1.667, 1: 1.667, 2: 6.667, 3: 6.667, 4: 1.667, 5: 1.667}
|
||||
for b in b_answer:
|
||||
b_answer[b] /= 2
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=False)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_disconnected_path(self):
|
||||
"""Betweenness centrality: disconnected path"""
|
||||
G = nx.Graph()
|
||||
nx.add_path(G, [0, 1, 2])
|
||||
nx.add_path(G, [3, 4, 5, 6])
|
||||
b_answer = {0: 0, 1: 1, 2: 0, 3: 0, 4: 2, 5: 2, 6: 0}
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=False)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_disconnected_path_endpoints(self):
|
||||
"""Betweenness centrality: disconnected path endpoints"""
|
||||
G = nx.Graph()
|
||||
nx.add_path(G, [0, 1, 2])
|
||||
nx.add_path(G, [3, 4, 5, 6])
|
||||
b_answer = {0: 2, 1: 3, 2: 2, 3: 3, 4: 5, 5: 5, 6: 3}
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=False, endpoints=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
# normalized = True case
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=True, endpoints=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n] / 21)
|
||||
|
||||
def test_directed_path(self):
|
||||
"""Betweenness centrality: directed path"""
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, [0, 1, 2])
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=False)
|
||||
b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_directed_path_normalized(self):
|
||||
"""Betweenness centrality: directed path normalized"""
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, [0, 1, 2])
|
||||
b = nx.betweenness_centrality(G, weight=None, normalized=True)
|
||||
b_answer = {0: 0.0, 1: 0.5, 2: 0.0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
|
||||
class TestWeightedBetweennessCentrality:
|
||||
def test_K5(self):
|
||||
"""Weighted betweenness centrality: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
b = nx.betweenness_centrality(G, weight="weight", normalized=False)
|
||||
b_answer = {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P3_normalized(self):
|
||||
"""Weighted betweenness centrality: P3 normalized"""
|
||||
G = nx.path_graph(3)
|
||||
b = nx.betweenness_centrality(G, weight="weight", normalized=True)
|
||||
b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P3(self):
|
||||
"""Weighted betweenness centrality: P3"""
|
||||
G = nx.path_graph(3)
|
||||
b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
|
||||
b = nx.betweenness_centrality(G, weight="weight", normalized=False)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_krackhardt_kite_graph(self):
|
||||
"""Weighted betweenness centrality: Krackhardt kite graph"""
|
||||
G = nx.krackhardt_kite_graph()
|
||||
b_answer = {
|
||||
0: 1.667,
|
||||
1: 1.667,
|
||||
2: 0.000,
|
||||
3: 7.333,
|
||||
4: 0.000,
|
||||
5: 16.667,
|
||||
6: 16.667,
|
||||
7: 28.000,
|
||||
8: 16.000,
|
||||
9: 0.000,
|
||||
}
|
||||
for b in b_answer:
|
||||
b_answer[b] /= 2
|
||||
|
||||
b = nx.betweenness_centrality(G, weight="weight", normalized=False)
|
||||
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_krackhardt_kite_graph_normalized(self):
|
||||
"""Weighted betweenness centrality:
|
||||
Krackhardt kite graph normalized
|
||||
"""
|
||||
G = nx.krackhardt_kite_graph()
|
||||
b_answer = {
|
||||
0: 0.023,
|
||||
1: 0.023,
|
||||
2: 0.000,
|
||||
3: 0.102,
|
||||
4: 0.000,
|
||||
5: 0.231,
|
||||
6: 0.231,
|
||||
7: 0.389,
|
||||
8: 0.222,
|
||||
9: 0.000,
|
||||
}
|
||||
b = nx.betweenness_centrality(G, weight="weight", normalized=True)
|
||||
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_florentine_families_graph(self):
|
||||
"""Weighted betweenness centrality:
|
||||
Florentine families graph"""
|
||||
G = nx.florentine_families_graph()
|
||||
b_answer = {
|
||||
"Acciaiuoli": 0.000,
|
||||
"Albizzi": 0.212,
|
||||
"Barbadori": 0.093,
|
||||
"Bischeri": 0.104,
|
||||
"Castellani": 0.055,
|
||||
"Ginori": 0.000,
|
||||
"Guadagni": 0.255,
|
||||
"Lamberteschi": 0.000,
|
||||
"Medici": 0.522,
|
||||
"Pazzi": 0.000,
|
||||
"Peruzzi": 0.022,
|
||||
"Ridolfi": 0.114,
|
||||
"Salviati": 0.143,
|
||||
"Strozzi": 0.103,
|
||||
"Tornabuoni": 0.092,
|
||||
}
|
||||
|
||||
b = nx.betweenness_centrality(G, weight="weight", normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_les_miserables_graph(self):
|
||||
"""Weighted betweenness centrality: Les Miserables graph"""
|
||||
G = nx.les_miserables_graph()
|
||||
b_answer = {
|
||||
"Napoleon": 0.000,
|
||||
"Myriel": 0.177,
|
||||
"MlleBaptistine": 0.000,
|
||||
"MmeMagloire": 0.000,
|
||||
"CountessDeLo": 0.000,
|
||||
"Geborand": 0.000,
|
||||
"Champtercier": 0.000,
|
||||
"Cravatte": 0.000,
|
||||
"Count": 0.000,
|
||||
"OldMan": 0.000,
|
||||
"Valjean": 0.454,
|
||||
"Labarre": 0.000,
|
||||
"Marguerite": 0.009,
|
||||
"MmeDeR": 0.000,
|
||||
"Isabeau": 0.000,
|
||||
"Gervais": 0.000,
|
||||
"Listolier": 0.000,
|
||||
"Tholomyes": 0.066,
|
||||
"Fameuil": 0.000,
|
||||
"Blacheville": 0.000,
|
||||
"Favourite": 0.000,
|
||||
"Dahlia": 0.000,
|
||||
"Zephine": 0.000,
|
||||
"Fantine": 0.114,
|
||||
"MmeThenardier": 0.046,
|
||||
"Thenardier": 0.129,
|
||||
"Cosette": 0.075,
|
||||
"Javert": 0.193,
|
||||
"Fauchelevent": 0.026,
|
||||
"Bamatabois": 0.080,
|
||||
"Perpetue": 0.000,
|
||||
"Simplice": 0.001,
|
||||
"Scaufflaire": 0.000,
|
||||
"Woman1": 0.000,
|
||||
"Judge": 0.000,
|
||||
"Champmathieu": 0.000,
|
||||
"Brevet": 0.000,
|
||||
"Chenildieu": 0.000,
|
||||
"Cochepaille": 0.000,
|
||||
"Pontmercy": 0.023,
|
||||
"Boulatruelle": 0.000,
|
||||
"Eponine": 0.023,
|
||||
"Anzelma": 0.000,
|
||||
"Woman2": 0.000,
|
||||
"MotherInnocent": 0.000,
|
||||
"Gribier": 0.000,
|
||||
"MmeBurgon": 0.026,
|
||||
"Jondrette": 0.000,
|
||||
"Gavroche": 0.285,
|
||||
"Gillenormand": 0.024,
|
||||
"Magnon": 0.005,
|
||||
"MlleGillenormand": 0.036,
|
||||
"MmePontmercy": 0.005,
|
||||
"MlleVaubois": 0.000,
|
||||
"LtGillenormand": 0.015,
|
||||
"Marius": 0.072,
|
||||
"BaronessT": 0.004,
|
||||
"Mabeuf": 0.089,
|
||||
"Enjolras": 0.003,
|
||||
"Combeferre": 0.000,
|
||||
"Prouvaire": 0.000,
|
||||
"Feuilly": 0.004,
|
||||
"Courfeyrac": 0.001,
|
||||
"Bahorel": 0.007,
|
||||
"Bossuet": 0.028,
|
||||
"Joly": 0.000,
|
||||
"Grantaire": 0.036,
|
||||
"MotherPlutarch": 0.000,
|
||||
"Gueulemer": 0.025,
|
||||
"Babet": 0.015,
|
||||
"Claquesous": 0.042,
|
||||
"Montparnasse": 0.050,
|
||||
"Toussaint": 0.011,
|
||||
"Child1": 0.000,
|
||||
"Child2": 0.000,
|
||||
"Brujon": 0.002,
|
||||
"MmeHucheloup": 0.034,
|
||||
}
|
||||
|
||||
b = nx.betweenness_centrality(G, weight="weight", normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_ladder_graph(self):
|
||||
"""Weighted betweenness centrality: Ladder graph"""
|
||||
G = nx.Graph() # ladder_graph(3)
|
||||
G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (4, 5), (3, 5)])
|
||||
b_answer = {0: 1.667, 1: 1.667, 2: 6.667, 3: 6.667, 4: 1.667, 5: 1.667}
|
||||
for b in b_answer:
|
||||
b_answer[b] /= 2
|
||||
b = nx.betweenness_centrality(G, weight="weight", normalized=False)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_G(self):
|
||||
"""Weighted betweenness centrality: G"""
|
||||
G = weighted_G()
|
||||
b_answer = {0: 2.0, 1: 0.0, 2: 4.0, 3: 3.0, 4: 4.0, 5: 0.0}
|
||||
b = nx.betweenness_centrality(G, weight="weight", normalized=False)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_G2(self):
|
||||
"""Weighted betweenness centrality: G2"""
|
||||
G = nx.DiGraph()
|
||||
G.add_weighted_edges_from(
|
||||
[
|
||||
("s", "u", 10),
|
||||
("s", "x", 5),
|
||||
("u", "v", 1),
|
||||
("u", "x", 2),
|
||||
("v", "y", 1),
|
||||
("x", "u", 3),
|
||||
("x", "v", 5),
|
||||
("x", "y", 2),
|
||||
("y", "s", 7),
|
||||
("y", "v", 6),
|
||||
]
|
||||
)
|
||||
|
||||
b_answer = {"y": 5.0, "x": 5.0, "s": 4.0, "u": 2.0, "v": 2.0}
|
||||
|
||||
b = nx.betweenness_centrality(G, weight="weight", normalized=False)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
|
||||
class TestEdgeBetweennessCentrality:
|
||||
def test_K5(self):
|
||||
"""Edge betweenness centrality: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
b = nx.edge_betweenness_centrality(G, weight=None, normalized=False)
|
||||
b_answer = dict.fromkeys(G.edges(), 1)
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_normalized_K5(self):
|
||||
"""Edge betweenness centrality: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
b = nx.edge_betweenness_centrality(G, weight=None, normalized=True)
|
||||
b_answer = dict.fromkeys(G.edges(), 1 / 10)
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_C4(self):
|
||||
"""Edge betweenness centrality: C4"""
|
||||
G = nx.cycle_graph(4)
|
||||
b = nx.edge_betweenness_centrality(G, weight=None, normalized=True)
|
||||
b_answer = {(0, 1): 2, (0, 3): 2, (1, 2): 2, (2, 3): 2}
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n] / 6)
|
||||
|
||||
def test_P4(self):
|
||||
"""Edge betweenness centrality: P4"""
|
||||
G = nx.path_graph(4)
|
||||
b = nx.edge_betweenness_centrality(G, weight=None, normalized=False)
|
||||
b_answer = {(0, 1): 3, (1, 2): 4, (2, 3): 3}
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_normalized_P4(self):
|
||||
"""Edge betweenness centrality: P4"""
|
||||
G = nx.path_graph(4)
|
||||
b = nx.edge_betweenness_centrality(G, weight=None, normalized=True)
|
||||
b_answer = {(0, 1): 3, (1, 2): 4, (2, 3): 3}
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n] / 6)
|
||||
|
||||
def test_balanced_tree(self):
|
||||
"""Edge betweenness centrality: balanced tree"""
|
||||
G = nx.balanced_tree(r=2, h=2)
|
||||
b = nx.edge_betweenness_centrality(G, weight=None, normalized=False)
|
||||
b_answer = {(0, 1): 12, (0, 2): 12, (1, 3): 6, (1, 4): 6, (2, 5): 6, (2, 6): 6}
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
|
||||
class TestWeightedEdgeBetweennessCentrality:
|
||||
def test_K5(self):
|
||||
"""Edge betweenness centrality: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
b = nx.edge_betweenness_centrality(G, weight="weight", normalized=False)
|
||||
b_answer = dict.fromkeys(G.edges(), 1)
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_C4(self):
|
||||
"""Edge betweenness centrality: C4"""
|
||||
G = nx.cycle_graph(4)
|
||||
b = nx.edge_betweenness_centrality(G, weight="weight", normalized=False)
|
||||
b_answer = {(0, 1): 2, (0, 3): 2, (1, 2): 2, (2, 3): 2}
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P4(self):
|
||||
"""Edge betweenness centrality: P4"""
|
||||
G = nx.path_graph(4)
|
||||
b = nx.edge_betweenness_centrality(G, weight="weight", normalized=False)
|
||||
b_answer = {(0, 1): 3, (1, 2): 4, (2, 3): 3}
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_balanced_tree(self):
|
||||
"""Edge betweenness centrality: balanced tree"""
|
||||
G = nx.balanced_tree(r=2, h=2)
|
||||
b = nx.edge_betweenness_centrality(G, weight="weight", normalized=False)
|
||||
b_answer = {(0, 1): 12, (0, 2): 12, (1, 3): 6, (1, 4): 6, (2, 5): 6, (2, 6): 6}
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_weighted_graph(self):
|
||||
eList = [
|
||||
(0, 1, 5),
|
||||
(0, 2, 4),
|
||||
(0, 3, 3),
|
||||
(0, 4, 2),
|
||||
(1, 2, 4),
|
||||
(1, 3, 1),
|
||||
(1, 4, 3),
|
||||
(2, 4, 5),
|
||||
(3, 4, 4),
|
||||
]
|
||||
G = nx.Graph()
|
||||
G.add_weighted_edges_from(eList)
|
||||
b = nx.edge_betweenness_centrality(G, weight="weight", normalized=False)
|
||||
b_answer = {
|
||||
(0, 1): 0.0,
|
||||
(0, 2): 1.0,
|
||||
(0, 3): 2.0,
|
||||
(0, 4): 1.0,
|
||||
(1, 2): 2.0,
|
||||
(1, 3): 3.5,
|
||||
(1, 4): 1.5,
|
||||
(2, 4): 1.0,
|
||||
(3, 4): 0.5,
|
||||
}
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_normalized_weighted_graph(self):
|
||||
eList = [
|
||||
(0, 1, 5),
|
||||
(0, 2, 4),
|
||||
(0, 3, 3),
|
||||
(0, 4, 2),
|
||||
(1, 2, 4),
|
||||
(1, 3, 1),
|
||||
(1, 4, 3),
|
||||
(2, 4, 5),
|
||||
(3, 4, 4),
|
||||
]
|
||||
G = nx.Graph()
|
||||
G.add_weighted_edges_from(eList)
|
||||
b = nx.edge_betweenness_centrality(G, weight="weight", normalized=True)
|
||||
b_answer = {
|
||||
(0, 1): 0.0,
|
||||
(0, 2): 1.0,
|
||||
(0, 3): 2.0,
|
||||
(0, 4): 1.0,
|
||||
(1, 2): 2.0,
|
||||
(1, 3): 3.5,
|
||||
(1, 4): 1.5,
|
||||
(2, 4): 1.0,
|
||||
(3, 4): 0.5,
|
||||
}
|
||||
norm = len(G) * (len(G) - 1) / 2
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n] / norm)
|
|
@ -0,0 +1,226 @@
|
|||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
class TestSubsetBetweennessCentrality:
|
||||
def test_K5(self):
|
||||
"""Betweenness Centrality Subset: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
b = nx.betweenness_centrality_subset(
|
||||
G, sources=[0], targets=[1, 3], weight=None
|
||||
)
|
||||
b_answer = {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P5_directed(self):
|
||||
"""Betweenness Centrality Subset: P5 directed"""
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, range(5))
|
||||
b_answer = {0: 0, 1: 1, 2: 1, 3: 0, 4: 0, 5: 0}
|
||||
b = nx.betweenness_centrality_subset(G, sources=[0], targets=[3], weight=None)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P5(self):
|
||||
"""Betweenness Centrality Subset: P5"""
|
||||
G = nx.Graph()
|
||||
nx.add_path(G, range(5))
|
||||
b_answer = {0: 0, 1: 0.5, 2: 0.5, 3: 0, 4: 0, 5: 0}
|
||||
b = nx.betweenness_centrality_subset(G, sources=[0], targets=[3], weight=None)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P5_multiple_target(self):
|
||||
"""Betweenness Centrality Subset: P5 multiple target"""
|
||||
G = nx.Graph()
|
||||
nx.add_path(G, range(5))
|
||||
b_answer = {0: 0, 1: 1, 2: 1, 3: 0.5, 4: 0, 5: 0}
|
||||
b = nx.betweenness_centrality_subset(
|
||||
G, sources=[0], targets=[3, 4], weight=None
|
||||
)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_box(self):
|
||||
"""Betweenness Centrality Subset: box"""
|
||||
G = nx.Graph()
|
||||
G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3)])
|
||||
b_answer = {0: 0, 1: 0.25, 2: 0.25, 3: 0}
|
||||
b = nx.betweenness_centrality_subset(G, sources=[0], targets=[3], weight=None)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_box_and_path(self):
|
||||
"""Betweenness Centrality Subset: box and path"""
|
||||
G = nx.Graph()
|
||||
G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (3, 4), (4, 5)])
|
||||
b_answer = {0: 0, 1: 0.5, 2: 0.5, 3: 0.5, 4: 0, 5: 0}
|
||||
b = nx.betweenness_centrality_subset(
|
||||
G, sources=[0], targets=[3, 4], weight=None
|
||||
)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_box_and_path2(self):
|
||||
"""Betweenness Centrality Subset: box and path multiple target"""
|
||||
G = nx.Graph()
|
||||
G.add_edges_from([(0, 1), (1, 2), (2, 3), (1, 20), (20, 3), (3, 4)])
|
||||
b_answer = {0: 0, 1: 1.0, 2: 0.5, 20: 0.5, 3: 0.5, 4: 0}
|
||||
b = nx.betweenness_centrality_subset(
|
||||
G, sources=[0], targets=[3, 4], weight=None
|
||||
)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_diamond_multi_path(self):
|
||||
"""Betweenness Centrality Subset: Diamond Multi Path"""
|
||||
G = nx.Graph()
|
||||
G.add_edges_from(
|
||||
[
|
||||
(1, 2),
|
||||
(1, 3),
|
||||
(1, 4),
|
||||
(1, 5),
|
||||
(1, 10),
|
||||
(10, 11),
|
||||
(11, 12),
|
||||
(12, 9),
|
||||
(2, 6),
|
||||
(3, 6),
|
||||
(4, 6),
|
||||
(5, 7),
|
||||
(7, 8),
|
||||
(6, 8),
|
||||
(8, 9),
|
||||
]
|
||||
)
|
||||
b = nx.betweenness_centrality_subset(G, sources=[1], targets=[9], weight=None)
|
||||
|
||||
expected_b = {
|
||||
1: 0,
|
||||
2: 1.0 / 10,
|
||||
3: 1.0 / 10,
|
||||
4: 1.0 / 10,
|
||||
5: 1.0 / 10,
|
||||
6: 3.0 / 10,
|
||||
7: 1.0 / 10,
|
||||
8: 4.0 / 10,
|
||||
9: 0,
|
||||
10: 1.0 / 10,
|
||||
11: 1.0 / 10,
|
||||
12: 1.0 / 10,
|
||||
}
|
||||
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], expected_b[n])
|
||||
|
||||
|
||||
class TestBetweennessCentralitySources:
|
||||
def test_K5(self):
|
||||
"""Betweenness Centrality Sources: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
b = nx.betweenness_centrality_source(G, weight=None, normalized=False)
|
||||
b_answer = {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P3(self):
|
||||
"""Betweenness Centrality Sources: P3"""
|
||||
G = nx.path_graph(3)
|
||||
b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
|
||||
b = nx.betweenness_centrality_source(G, weight=None, normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
|
||||
class TestEdgeSubsetBetweennessCentrality:
|
||||
def test_K5(self):
|
||||
"""Edge betweenness subset centrality: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
b = nx.edge_betweenness_centrality_subset(
|
||||
G, sources=[0], targets=[1, 3], weight=None
|
||||
)
|
||||
b_answer = dict.fromkeys(G.edges(), 0)
|
||||
b_answer[(0, 3)] = b_answer[(0, 1)] = 0.5
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P5_directed(self):
|
||||
"""Edge betweenness subset centrality: P5 directed"""
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, range(5))
|
||||
b_answer = dict.fromkeys(G.edges(), 0)
|
||||
b_answer[(0, 1)] = b_answer[(1, 2)] = b_answer[(2, 3)] = 1
|
||||
b = nx.edge_betweenness_centrality_subset(
|
||||
G, sources=[0], targets=[3], weight=None
|
||||
)
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P5(self):
|
||||
"""Edge betweenness subset centrality: P5"""
|
||||
G = nx.Graph()
|
||||
nx.add_path(G, range(5))
|
||||
b_answer = dict.fromkeys(G.edges(), 0)
|
||||
b_answer[(0, 1)] = b_answer[(1, 2)] = b_answer[(2, 3)] = 0.5
|
||||
b = nx.edge_betweenness_centrality_subset(
|
||||
G, sources=[0], targets=[3], weight=None
|
||||
)
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P5_multiple_target(self):
|
||||
"""Edge betweenness subset centrality: P5 multiple target"""
|
||||
G = nx.Graph()
|
||||
nx.add_path(G, range(5))
|
||||
b_answer = dict.fromkeys(G.edges(), 0)
|
||||
b_answer[(0, 1)] = b_answer[(1, 2)] = b_answer[(2, 3)] = 1
|
||||
b_answer[(3, 4)] = 0.5
|
||||
b = nx.edge_betweenness_centrality_subset(
|
||||
G, sources=[0], targets=[3, 4], weight=None
|
||||
)
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_box(self):
|
||||
"""Edge betweenness subset centrality: box"""
|
||||
G = nx.Graph()
|
||||
G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3)])
|
||||
b_answer = dict.fromkeys(G.edges(), 0)
|
||||
b_answer[(0, 1)] = b_answer[(0, 2)] = 0.25
|
||||
b_answer[(1, 3)] = b_answer[(2, 3)] = 0.25
|
||||
b = nx.edge_betweenness_centrality_subset(
|
||||
G, sources=[0], targets=[3], weight=None
|
||||
)
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_box_and_path(self):
|
||||
"""Edge betweenness subset centrality: box and path"""
|
||||
G = nx.Graph()
|
||||
G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (3, 4), (4, 5)])
|
||||
b_answer = dict.fromkeys(G.edges(), 0)
|
||||
b_answer[(0, 1)] = b_answer[(0, 2)] = 0.5
|
||||
b_answer[(1, 3)] = b_answer[(2, 3)] = 0.5
|
||||
b_answer[(3, 4)] = 0.5
|
||||
b = nx.edge_betweenness_centrality_subset(
|
||||
G, sources=[0], targets=[3, 4], weight=None
|
||||
)
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_box_and_path2(self):
|
||||
"""Edge betweenness subset centrality: box and path multiple target"""
|
||||
G = nx.Graph()
|
||||
G.add_edges_from([(0, 1), (1, 2), (2, 3), (1, 20), (20, 3), (3, 4)])
|
||||
b_answer = dict.fromkeys(G.edges(), 0)
|
||||
b_answer[(0, 1)] = 1.0
|
||||
b_answer[(1, 20)] = b_answer[(3, 20)] = 0.5
|
||||
b_answer[(1, 2)] = b_answer[(2, 3)] = 0.5
|
||||
b_answer[(3, 4)] = 0.5
|
||||
b = nx.edge_betweenness_centrality_subset(
|
||||
G, sources=[0], targets=[3, 4], weight=None
|
||||
)
|
||||
for n in sorted(G.edges()):
|
||||
assert almost_equal(b[n], b_answer[n])
|
|
@ -0,0 +1,306 @@
|
|||
"""
|
||||
Tests for closeness centrality.
|
||||
"""
|
||||
import pytest
|
||||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
class TestClosenessCentrality:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
cls.K = nx.krackhardt_kite_graph()
|
||||
cls.P3 = nx.path_graph(3)
|
||||
cls.P4 = nx.path_graph(4)
|
||||
cls.K5 = nx.complete_graph(5)
|
||||
|
||||
cls.C4 = nx.cycle_graph(4)
|
||||
cls.T = nx.balanced_tree(r=2, h=2)
|
||||
cls.Gb = nx.Graph()
|
||||
cls.Gb.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (4, 5), (3, 5)])
|
||||
|
||||
F = nx.florentine_families_graph()
|
||||
cls.F = F
|
||||
|
||||
cls.LM = nx.les_miserables_graph()
|
||||
|
||||
# Create random undirected, unweighted graph for testing incremental version
|
||||
cls.undirected_G = nx.fast_gnp_random_graph(n=100, p=0.6, seed=123)
|
||||
cls.undirected_G_cc = nx.closeness_centrality(cls.undirected_G)
|
||||
|
||||
def test_wf_improved(self):
|
||||
G = nx.union(self.P4, nx.path_graph([4, 5, 6]))
|
||||
c = nx.closeness_centrality(G)
|
||||
cwf = nx.closeness_centrality(G, wf_improved=False)
|
||||
res = {0: 0.25, 1: 0.375, 2: 0.375, 3: 0.25, 4: 0.222, 5: 0.333, 6: 0.222}
|
||||
wf_res = {0: 0.5, 1: 0.75, 2: 0.75, 3: 0.5, 4: 0.667, 5: 1.0, 6: 0.667}
|
||||
for n in G:
|
||||
assert almost_equal(c[n], res[n], places=3)
|
||||
assert almost_equal(cwf[n], wf_res[n], places=3)
|
||||
|
||||
def test_digraph(self):
|
||||
G = nx.path_graph(3, create_using=nx.DiGraph())
|
||||
c = nx.closeness_centrality(G)
|
||||
cr = nx.closeness_centrality(G.reverse())
|
||||
d = {0: 0.0, 1: 0.500, 2: 0.667}
|
||||
dr = {0: 0.667, 1: 0.500, 2: 0.0}
|
||||
for n in sorted(self.P3):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
assert almost_equal(cr[n], dr[n], places=3)
|
||||
|
||||
def test_k5_closeness(self):
|
||||
c = nx.closeness_centrality(self.K5)
|
||||
d = {0: 1.000, 1: 1.000, 2: 1.000, 3: 1.000, 4: 1.000}
|
||||
for n in sorted(self.K5):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_p3_closeness(self):
|
||||
c = nx.closeness_centrality(self.P3)
|
||||
d = {0: 0.667, 1: 1.000, 2: 0.667}
|
||||
for n in sorted(self.P3):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_krackhardt_closeness(self):
|
||||
c = nx.closeness_centrality(self.K)
|
||||
d = {
|
||||
0: 0.529,
|
||||
1: 0.529,
|
||||
2: 0.500,
|
||||
3: 0.600,
|
||||
4: 0.500,
|
||||
5: 0.643,
|
||||
6: 0.643,
|
||||
7: 0.600,
|
||||
8: 0.429,
|
||||
9: 0.310,
|
||||
}
|
||||
for n in sorted(self.K):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_florentine_families_closeness(self):
|
||||
c = nx.closeness_centrality(self.F)
|
||||
d = {
|
||||
"Acciaiuoli": 0.368,
|
||||
"Albizzi": 0.483,
|
||||
"Barbadori": 0.4375,
|
||||
"Bischeri": 0.400,
|
||||
"Castellani": 0.389,
|
||||
"Ginori": 0.333,
|
||||
"Guadagni": 0.467,
|
||||
"Lamberteschi": 0.326,
|
||||
"Medici": 0.560,
|
||||
"Pazzi": 0.286,
|
||||
"Peruzzi": 0.368,
|
||||
"Ridolfi": 0.500,
|
||||
"Salviati": 0.389,
|
||||
"Strozzi": 0.4375,
|
||||
"Tornabuoni": 0.483,
|
||||
}
|
||||
for n in sorted(self.F):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_les_miserables_closeness(self):
|
||||
c = nx.closeness_centrality(self.LM)
|
||||
d = {
|
||||
"Napoleon": 0.302,
|
||||
"Myriel": 0.429,
|
||||
"MlleBaptistine": 0.413,
|
||||
"MmeMagloire": 0.413,
|
||||
"CountessDeLo": 0.302,
|
||||
"Geborand": 0.302,
|
||||
"Champtercier": 0.302,
|
||||
"Cravatte": 0.302,
|
||||
"Count": 0.302,
|
||||
"OldMan": 0.302,
|
||||
"Valjean": 0.644,
|
||||
"Labarre": 0.394,
|
||||
"Marguerite": 0.413,
|
||||
"MmeDeR": 0.394,
|
||||
"Isabeau": 0.394,
|
||||
"Gervais": 0.394,
|
||||
"Listolier": 0.341,
|
||||
"Tholomyes": 0.392,
|
||||
"Fameuil": 0.341,
|
||||
"Blacheville": 0.341,
|
||||
"Favourite": 0.341,
|
||||
"Dahlia": 0.341,
|
||||
"Zephine": 0.341,
|
||||
"Fantine": 0.461,
|
||||
"MmeThenardier": 0.461,
|
||||
"Thenardier": 0.517,
|
||||
"Cosette": 0.478,
|
||||
"Javert": 0.517,
|
||||
"Fauchelevent": 0.402,
|
||||
"Bamatabois": 0.427,
|
||||
"Perpetue": 0.318,
|
||||
"Simplice": 0.418,
|
||||
"Scaufflaire": 0.394,
|
||||
"Woman1": 0.396,
|
||||
"Judge": 0.404,
|
||||
"Champmathieu": 0.404,
|
||||
"Brevet": 0.404,
|
||||
"Chenildieu": 0.404,
|
||||
"Cochepaille": 0.404,
|
||||
"Pontmercy": 0.373,
|
||||
"Boulatruelle": 0.342,
|
||||
"Eponine": 0.396,
|
||||
"Anzelma": 0.352,
|
||||
"Woman2": 0.402,
|
||||
"MotherInnocent": 0.398,
|
||||
"Gribier": 0.288,
|
||||
"MmeBurgon": 0.344,
|
||||
"Jondrette": 0.257,
|
||||
"Gavroche": 0.514,
|
||||
"Gillenormand": 0.442,
|
||||
"Magnon": 0.335,
|
||||
"MlleGillenormand": 0.442,
|
||||
"MmePontmercy": 0.315,
|
||||
"MlleVaubois": 0.308,
|
||||
"LtGillenormand": 0.365,
|
||||
"Marius": 0.531,
|
||||
"BaronessT": 0.352,
|
||||
"Mabeuf": 0.396,
|
||||
"Enjolras": 0.481,
|
||||
"Combeferre": 0.392,
|
||||
"Prouvaire": 0.357,
|
||||
"Feuilly": 0.392,
|
||||
"Courfeyrac": 0.400,
|
||||
"Bahorel": 0.394,
|
||||
"Bossuet": 0.475,
|
||||
"Joly": 0.394,
|
||||
"Grantaire": 0.358,
|
||||
"MotherPlutarch": 0.285,
|
||||
"Gueulemer": 0.463,
|
||||
"Babet": 0.463,
|
||||
"Claquesous": 0.452,
|
||||
"Montparnasse": 0.458,
|
||||
"Toussaint": 0.402,
|
||||
"Child1": 0.342,
|
||||
"Child2": 0.342,
|
||||
"Brujon": 0.380,
|
||||
"MmeHucheloup": 0.353,
|
||||
}
|
||||
for n in sorted(self.LM):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_weighted_closeness(self):
|
||||
edges = [
|
||||
("s", "u", 10),
|
||||
("s", "x", 5),
|
||||
("u", "v", 1),
|
||||
("u", "x", 2),
|
||||
("v", "y", 1),
|
||||
("x", "u", 3),
|
||||
("x", "v", 5),
|
||||
("x", "y", 2),
|
||||
("y", "s", 7),
|
||||
("y", "v", 6),
|
||||
]
|
||||
XG = nx.Graph()
|
||||
XG.add_weighted_edges_from(edges)
|
||||
c = nx.closeness_centrality(XG, distance="weight")
|
||||
d = {"y": 0.200, "x": 0.286, "s": 0.138, "u": 0.235, "v": 0.200}
|
||||
for n in sorted(XG):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
#
|
||||
# Tests for incremental closeness centrality.
|
||||
#
|
||||
@staticmethod
|
||||
def pick_add_edge(g):
|
||||
u = nx.utils.arbitrary_element(g)
|
||||
possible_nodes = set(g.nodes())
|
||||
neighbors = list(g.neighbors(u)) + [u]
|
||||
possible_nodes.difference_update(neighbors)
|
||||
v = nx.utils.arbitrary_element(possible_nodes)
|
||||
return (u, v)
|
||||
|
||||
@staticmethod
|
||||
def pick_remove_edge(g):
|
||||
u = nx.utils.arbitrary_element(g)
|
||||
possible_nodes = list(g.neighbors(u))
|
||||
v = nx.utils.arbitrary_element(possible_nodes)
|
||||
return (u, v)
|
||||
|
||||
def test_directed_raises(self):
|
||||
with pytest.raises(nx.NetworkXNotImplemented):
|
||||
dir_G = nx.gn_graph(n=5)
|
||||
prev_cc = None
|
||||
edge = self.pick_add_edge(dir_G)
|
||||
insert = True
|
||||
nx.incremental_closeness_centrality(dir_G, edge, prev_cc, insert)
|
||||
|
||||
def test_wrong_size_prev_cc_raises(self):
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
G = self.undirected_G.copy()
|
||||
edge = self.pick_add_edge(G)
|
||||
insert = True
|
||||
prev_cc = self.undirected_G_cc.copy()
|
||||
prev_cc.pop(0)
|
||||
nx.incremental_closeness_centrality(G, edge, prev_cc, insert)
|
||||
|
||||
def test_wrong_nodes_prev_cc_raises(self):
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
G = self.undirected_G.copy()
|
||||
edge = self.pick_add_edge(G)
|
||||
insert = True
|
||||
prev_cc = self.undirected_G_cc.copy()
|
||||
num_nodes = len(prev_cc)
|
||||
prev_cc.pop(0)
|
||||
prev_cc[num_nodes] = 0.5
|
||||
nx.incremental_closeness_centrality(G, edge, prev_cc, insert)
|
||||
|
||||
def test_zero_centrality(self):
|
||||
G = nx.path_graph(3)
|
||||
prev_cc = nx.closeness_centrality(G)
|
||||
edge = self.pick_remove_edge(G)
|
||||
test_cc = nx.incremental_closeness_centrality(G, edge, prev_cc, insertion=False)
|
||||
G.remove_edges_from([edge])
|
||||
real_cc = nx.closeness_centrality(G)
|
||||
shared_items = set(test_cc.items()) & set(real_cc.items())
|
||||
assert len(shared_items) == len(real_cc)
|
||||
assert 0 in test_cc.values()
|
||||
|
||||
def test_incremental(self):
|
||||
# Check that incremental and regular give same output
|
||||
G = self.undirected_G.copy()
|
||||
prev_cc = None
|
||||
for i in range(5):
|
||||
if i % 2 == 0:
|
||||
# Remove an edge
|
||||
insert = False
|
||||
edge = self.pick_remove_edge(G)
|
||||
else:
|
||||
# Add an edge
|
||||
insert = True
|
||||
edge = self.pick_add_edge(G)
|
||||
|
||||
# start = timeit.default_timer()
|
||||
test_cc = nx.incremental_closeness_centrality(G, edge, prev_cc, insert)
|
||||
# inc_elapsed = (timeit.default_timer() - start)
|
||||
# print(f"incremental time: {inc_elapsed}")
|
||||
|
||||
if insert:
|
||||
G.add_edges_from([edge])
|
||||
else:
|
||||
G.remove_edges_from([edge])
|
||||
|
||||
# start = timeit.default_timer()
|
||||
real_cc = nx.closeness_centrality(G)
|
||||
# reg_elapsed = (timeit.default_timer() - start)
|
||||
# print(f"regular time: {reg_elapsed}")
|
||||
# Example output:
|
||||
# incremental time: 0.208
|
||||
# regular time: 0.276
|
||||
# incremental time: 0.00683
|
||||
# regular time: 0.260
|
||||
# incremental time: 0.0224
|
||||
# regular time: 0.278
|
||||
# incremental time: 0.00804
|
||||
# regular time: 0.208
|
||||
# incremental time: 0.00947
|
||||
# regular time: 0.188
|
||||
|
||||
assert set(test_cc.items()) == set(real_cc.items())
|
||||
|
||||
prev_cc = test_cc
|
|
@ -0,0 +1,180 @@
|
|||
import pytest
|
||||
|
||||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
from networkx import edge_current_flow_betweenness_centrality as edge_current_flow
|
||||
from networkx import approximate_current_flow_betweenness_centrality as approximate_cfbc
|
||||
|
||||
|
||||
np = pytest.importorskip("numpy")
|
||||
npt = pytest.importorskip("numpy.testing")
|
||||
scipy = pytest.importorskip("scipy")
|
||||
|
||||
|
||||
class TestFlowBetweennessCentrality:
|
||||
def test_K4_normalized(self):
|
||||
"""Betweenness centrality: K4"""
|
||||
G = nx.complete_graph(4)
|
||||
b = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
b_answer = {0: 0.25, 1: 0.25, 2: 0.25, 3: 0.25}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
G.add_edge(0, 1, weight=0.5, other=0.3)
|
||||
b = nx.current_flow_betweenness_centrality(G, normalized=True, weight=None)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
wb_answer = {0: 0.2222222, 1: 0.2222222, 2: 0.30555555, 3: 0.30555555}
|
||||
b = nx.current_flow_betweenness_centrality(G, normalized=True, weight="weight")
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], wb_answer[n])
|
||||
wb_answer = {0: 0.2051282, 1: 0.2051282, 2: 0.33974358, 3: 0.33974358}
|
||||
b = nx.current_flow_betweenness_centrality(G, normalized=True, weight="other")
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], wb_answer[n])
|
||||
|
||||
def test_K4(self):
|
||||
"""Betweenness centrality: K4"""
|
||||
G = nx.complete_graph(4)
|
||||
for solver in ["full", "lu", "cg"]:
|
||||
b = nx.current_flow_betweenness_centrality(
|
||||
G, normalized=False, solver=solver
|
||||
)
|
||||
b_answer = {0: 0.75, 1: 0.75, 2: 0.75, 3: 0.75}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P4_normalized(self):
|
||||
"""Betweenness centrality: P4 normalized"""
|
||||
G = nx.path_graph(4)
|
||||
b = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
b_answer = {0: 0, 1: 2.0 / 3, 2: 2.0 / 3, 3: 0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P4(self):
|
||||
"""Betweenness centrality: P4"""
|
||||
G = nx.path_graph(4)
|
||||
b = nx.current_flow_betweenness_centrality(G, normalized=False)
|
||||
b_answer = {0: 0, 1: 2, 2: 2, 3: 0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_star(self):
|
||||
"""Betweenness centrality: star """
|
||||
G = nx.Graph()
|
||||
nx.add_star(G, ["a", "b", "c", "d"])
|
||||
b = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
b_answer = {"a": 1.0, "b": 0.0, "c": 0.0, "d": 0.0}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_solvers2(self):
|
||||
"""Betweenness centrality: alternate solvers"""
|
||||
G = nx.complete_graph(4)
|
||||
for solver in ["full", "lu", "cg"]:
|
||||
b = nx.current_flow_betweenness_centrality(
|
||||
G, normalized=False, solver=solver
|
||||
)
|
||||
b_answer = {0: 0.75, 1: 0.75, 2: 0.75, 3: 0.75}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
|
||||
class TestApproximateFlowBetweennessCentrality:
|
||||
def test_K4_normalized(self):
|
||||
"Approximate current-flow betweenness centrality: K4 normalized"
|
||||
G = nx.complete_graph(4)
|
||||
b = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
epsilon = 0.1
|
||||
ba = approximate_cfbc(G, normalized=True, epsilon=0.5 * epsilon)
|
||||
for n in sorted(G):
|
||||
npt.assert_allclose(b[n], ba[n], atol=epsilon)
|
||||
|
||||
def test_K4(self):
|
||||
"Approximate current-flow betweenness centrality: K4"
|
||||
G = nx.complete_graph(4)
|
||||
b = nx.current_flow_betweenness_centrality(G, normalized=False)
|
||||
epsilon = 0.1
|
||||
ba = approximate_cfbc(G, normalized=False, epsilon=0.5 * epsilon)
|
||||
for n in sorted(G):
|
||||
npt.assert_allclose(b[n], ba[n], atol=epsilon * len(G) ** 2)
|
||||
|
||||
def test_star(self):
|
||||
"Approximate current-flow betweenness centrality: star"
|
||||
G = nx.Graph()
|
||||
nx.add_star(G, ["a", "b", "c", "d"])
|
||||
b = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
epsilon = 0.1
|
||||
ba = approximate_cfbc(G, normalized=True, epsilon=0.5 * epsilon)
|
||||
for n in sorted(G):
|
||||
npt.assert_allclose(b[n], ba[n], atol=epsilon)
|
||||
|
||||
def test_grid(self):
|
||||
"Approximate current-flow betweenness centrality: 2d grid"
|
||||
G = nx.grid_2d_graph(4, 4)
|
||||
b = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
epsilon = 0.1
|
||||
ba = approximate_cfbc(G, normalized=True, epsilon=0.5 * epsilon)
|
||||
for n in sorted(G):
|
||||
npt.assert_allclose(b[n], ba[n], atol=epsilon)
|
||||
|
||||
def test_seed(self):
|
||||
G = nx.complete_graph(4)
|
||||
b = approximate_cfbc(G, normalized=False, epsilon=0.05, seed=1)
|
||||
b_answer = {0: 0.75, 1: 0.75, 2: 0.75, 3: 0.75}
|
||||
for n in sorted(G):
|
||||
npt.assert_allclose(b[n], b_answer[n], atol=0.1)
|
||||
|
||||
def test_solvers(self):
|
||||
"Approximate current-flow betweenness centrality: solvers"
|
||||
G = nx.complete_graph(4)
|
||||
epsilon = 0.1
|
||||
for solver in ["full", "lu", "cg"]:
|
||||
b = approximate_cfbc(
|
||||
G, normalized=False, solver=solver, epsilon=0.5 * epsilon
|
||||
)
|
||||
b_answer = {0: 0.75, 1: 0.75, 2: 0.75, 3: 0.75}
|
||||
for n in sorted(G):
|
||||
npt.assert_allclose(b[n], b_answer[n], atol=epsilon)
|
||||
|
||||
|
||||
class TestWeightedFlowBetweennessCentrality:
|
||||
pass
|
||||
|
||||
|
||||
class TestEdgeFlowBetweennessCentrality:
|
||||
def test_K4(self):
|
||||
"""Edge flow betweenness centrality: K4"""
|
||||
G = nx.complete_graph(4)
|
||||
b = edge_current_flow(G, normalized=True)
|
||||
b_answer = dict.fromkeys(G.edges(), 0.25)
|
||||
for (s, t), v1 in b_answer.items():
|
||||
v2 = b.get((s, t), b.get((t, s)))
|
||||
assert almost_equal(v1, v2)
|
||||
|
||||
def test_K4_normalized(self):
|
||||
"""Edge flow betweenness centrality: K4"""
|
||||
G = nx.complete_graph(4)
|
||||
b = edge_current_flow(G, normalized=False)
|
||||
b_answer = dict.fromkeys(G.edges(), 0.75)
|
||||
for (s, t), v1 in b_answer.items():
|
||||
v2 = b.get((s, t), b.get((t, s)))
|
||||
assert almost_equal(v1, v2)
|
||||
|
||||
def test_C4(self):
|
||||
"""Edge flow betweenness centrality: C4"""
|
||||
G = nx.cycle_graph(4)
|
||||
b = edge_current_flow(G, normalized=False)
|
||||
b_answer = {(0, 1): 1.25, (0, 3): 1.25, (1, 2): 1.25, (2, 3): 1.25}
|
||||
for (s, t), v1 in b_answer.items():
|
||||
v2 = b.get((s, t), b.get((t, s)))
|
||||
assert almost_equal(v1, v2)
|
||||
|
||||
def test_P4(self):
|
||||
"""Edge betweenness centrality: P4"""
|
||||
G = nx.path_graph(4)
|
||||
b = edge_current_flow(G, normalized=False)
|
||||
b_answer = {(0, 1): 1.5, (1, 2): 2.0, (2, 3): 1.5}
|
||||
for (s, t), v1 in b_answer.items():
|
||||
v2 = b.get((s, t), b.get((t, s)))
|
||||
assert almost_equal(v1, v2)
|
|
@ -0,0 +1,150 @@
|
|||
import pytest
|
||||
|
||||
np = pytest.importorskip("numpy")
|
||||
scipy = pytest.importorskip("scipy")
|
||||
|
||||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
from networkx import edge_current_flow_betweenness_centrality as edge_current_flow
|
||||
|
||||
from networkx import (
|
||||
edge_current_flow_betweenness_centrality_subset as edge_current_flow_subset,
|
||||
)
|
||||
|
||||
|
||||
class TestFlowBetweennessCentrality:
|
||||
def test_K4_normalized(self):
|
||||
"""Betweenness centrality: K4"""
|
||||
G = nx.complete_graph(4)
|
||||
b = nx.current_flow_betweenness_centrality_subset(
|
||||
G, list(G), list(G), normalized=True
|
||||
)
|
||||
b_answer = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_K4(self):
|
||||
"""Betweenness centrality: K4"""
|
||||
G = nx.complete_graph(4)
|
||||
b = nx.current_flow_betweenness_centrality_subset(
|
||||
G, list(G), list(G), normalized=True
|
||||
)
|
||||
b_answer = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
# test weighted network
|
||||
G.add_edge(0, 1, weight=0.5, other=0.3)
|
||||
b = nx.current_flow_betweenness_centrality_subset(
|
||||
G, list(G), list(G), normalized=True, weight=None
|
||||
)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
b = nx.current_flow_betweenness_centrality_subset(
|
||||
G, list(G), list(G), normalized=True
|
||||
)
|
||||
b_answer = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
b = nx.current_flow_betweenness_centrality_subset(
|
||||
G, list(G), list(G), normalized=True, weight="other"
|
||||
)
|
||||
b_answer = nx.current_flow_betweenness_centrality(
|
||||
G, normalized=True, weight="other"
|
||||
)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P4_normalized(self):
|
||||
"""Betweenness centrality: P4 normalized"""
|
||||
G = nx.path_graph(4)
|
||||
b = nx.current_flow_betweenness_centrality_subset(
|
||||
G, list(G), list(G), normalized=True
|
||||
)
|
||||
b_answer = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P4(self):
|
||||
"""Betweenness centrality: P4"""
|
||||
G = nx.path_graph(4)
|
||||
b = nx.current_flow_betweenness_centrality_subset(
|
||||
G, list(G), list(G), normalized=True
|
||||
)
|
||||
b_answer = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_star(self):
|
||||
"""Betweenness centrality: star """
|
||||
G = nx.Graph()
|
||||
nx.add_star(G, ["a", "b", "c", "d"])
|
||||
b = nx.current_flow_betweenness_centrality_subset(
|
||||
G, list(G), list(G), normalized=True
|
||||
)
|
||||
b_answer = nx.current_flow_betweenness_centrality(G, normalized=True)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
|
||||
# class TestWeightedFlowBetweennessCentrality():
|
||||
# pass
|
||||
|
||||
|
||||
class TestEdgeFlowBetweennessCentrality:
|
||||
def test_K4_normalized(self):
|
||||
"""Betweenness centrality: K4"""
|
||||
G = nx.complete_graph(4)
|
||||
b = edge_current_flow_subset(G, list(G), list(G), normalized=True)
|
||||
b_answer = edge_current_flow(G, normalized=True)
|
||||
for (s, t), v1 in b_answer.items():
|
||||
v2 = b.get((s, t), b.get((t, s)))
|
||||
assert almost_equal(v1, v2)
|
||||
|
||||
def test_K4(self):
|
||||
"""Betweenness centrality: K4"""
|
||||
G = nx.complete_graph(4)
|
||||
b = edge_current_flow_subset(G, list(G), list(G), normalized=False)
|
||||
b_answer = edge_current_flow(G, normalized=False)
|
||||
for (s, t), v1 in b_answer.items():
|
||||
v2 = b.get((s, t), b.get((t, s)))
|
||||
assert almost_equal(v1, v2)
|
||||
# test weighted network
|
||||
G.add_edge(0, 1, weight=0.5, other=0.3)
|
||||
b = edge_current_flow_subset(G, list(G), list(G), normalized=False, weight=None)
|
||||
# weight is None => same as unweighted network
|
||||
for (s, t), v1 in b_answer.items():
|
||||
v2 = b.get((s, t), b.get((t, s)))
|
||||
assert almost_equal(v1, v2)
|
||||
|
||||
b = edge_current_flow_subset(G, list(G), list(G), normalized=False)
|
||||
b_answer = edge_current_flow(G, normalized=False)
|
||||
for (s, t), v1 in b_answer.items():
|
||||
v2 = b.get((s, t), b.get((t, s)))
|
||||
assert almost_equal(v1, v2)
|
||||
|
||||
b = edge_current_flow_subset(
|
||||
G, list(G), list(G), normalized=False, weight="other"
|
||||
)
|
||||
b_answer = edge_current_flow(G, normalized=False, weight="other")
|
||||
for (s, t), v1 in b_answer.items():
|
||||
v2 = b.get((s, t), b.get((t, s)))
|
||||
assert almost_equal(v1, v2)
|
||||
|
||||
def test_C4(self):
|
||||
"""Edge betweenness centrality: C4"""
|
||||
G = nx.cycle_graph(4)
|
||||
b = edge_current_flow_subset(G, list(G), list(G), normalized=True)
|
||||
b_answer = edge_current_flow(G, normalized=True)
|
||||
for (s, t), v1 in b_answer.items():
|
||||
v2 = b.get((s, t), b.get((t, s)))
|
||||
assert almost_equal(v1, v2)
|
||||
|
||||
def test_P4(self):
|
||||
"""Edge betweenness centrality: P4"""
|
||||
G = nx.path_graph(4)
|
||||
b = edge_current_flow_subset(G, list(G), list(G), normalized=True)
|
||||
b_answer = edge_current_flow(G, normalized=True)
|
||||
for (s, t), v1 in b_answer.items():
|
||||
v2 = b.get((s, t), b.get((t, s)))
|
||||
assert almost_equal(v1, v2)
|
|
@ -0,0 +1,38 @@
|
|||
import pytest
|
||||
|
||||
np = pytest.importorskip("numpy")
|
||||
scipy = pytest.importorskip("scipy")
|
||||
|
||||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
class TestFlowClosenessCentrality:
|
||||
def test_K4(self):
|
||||
"""Closeness centrality: K4"""
|
||||
G = nx.complete_graph(4)
|
||||
b = nx.current_flow_closeness_centrality(G)
|
||||
b_answer = {0: 2.0 / 3, 1: 2.0 / 3, 2: 2.0 / 3, 3: 2.0 / 3}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P4(self):
|
||||
"""Closeness centrality: P4"""
|
||||
G = nx.path_graph(4)
|
||||
b = nx.current_flow_closeness_centrality(G)
|
||||
b_answer = {0: 1.0 / 6, 1: 1.0 / 4, 2: 1.0 / 4, 3: 1.0 / 6}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_star(self):
|
||||
"""Closeness centrality: star """
|
||||
G = nx.Graph()
|
||||
nx.add_star(G, ["a", "b", "c", "d"])
|
||||
b = nx.current_flow_closeness_centrality(G)
|
||||
b_answer = {"a": 1.0 / 3, "b": 0.6 / 3, "c": 0.6 / 3, "d": 0.6 / 3}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
|
||||
class TestWeightedFlowClosenessCentrality:
|
||||
pass
|
|
@ -0,0 +1,145 @@
|
|||
"""
|
||||
Unit tests for degree centrality.
|
||||
"""
|
||||
|
||||
|
||||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
class TestDegreeCentrality:
|
||||
def setup_method(self):
|
||||
|
||||
self.K = nx.krackhardt_kite_graph()
|
||||
self.P3 = nx.path_graph(3)
|
||||
self.K5 = nx.complete_graph(5)
|
||||
|
||||
F = nx.Graph() # Florentine families
|
||||
F.add_edge("Acciaiuoli", "Medici")
|
||||
F.add_edge("Castellani", "Peruzzi")
|
||||
F.add_edge("Castellani", "Strozzi")
|
||||
F.add_edge("Castellani", "Barbadori")
|
||||
F.add_edge("Medici", "Barbadori")
|
||||
F.add_edge("Medici", "Ridolfi")
|
||||
F.add_edge("Medici", "Tornabuoni")
|
||||
F.add_edge("Medici", "Albizzi")
|
||||
F.add_edge("Medici", "Salviati")
|
||||
F.add_edge("Salviati", "Pazzi")
|
||||
F.add_edge("Peruzzi", "Strozzi")
|
||||
F.add_edge("Peruzzi", "Bischeri")
|
||||
F.add_edge("Strozzi", "Ridolfi")
|
||||
F.add_edge("Strozzi", "Bischeri")
|
||||
F.add_edge("Ridolfi", "Tornabuoni")
|
||||
F.add_edge("Tornabuoni", "Guadagni")
|
||||
F.add_edge("Albizzi", "Ginori")
|
||||
F.add_edge("Albizzi", "Guadagni")
|
||||
F.add_edge("Bischeri", "Guadagni")
|
||||
F.add_edge("Guadagni", "Lamberteschi")
|
||||
self.F = F
|
||||
|
||||
G = nx.DiGraph()
|
||||
G.add_edge(0, 5)
|
||||
G.add_edge(1, 5)
|
||||
G.add_edge(2, 5)
|
||||
G.add_edge(3, 5)
|
||||
G.add_edge(4, 5)
|
||||
G.add_edge(5, 6)
|
||||
G.add_edge(5, 7)
|
||||
G.add_edge(5, 8)
|
||||
self.G = G
|
||||
|
||||
def test_degree_centrality_1(self):
|
||||
d = nx.degree_centrality(self.K5)
|
||||
exact = dict(zip(range(5), [1] * 5))
|
||||
for n, dc in d.items():
|
||||
assert almost_equal(exact[n], dc)
|
||||
|
||||
def test_degree_centrality_2(self):
|
||||
d = nx.degree_centrality(self.P3)
|
||||
exact = {0: 0.5, 1: 1, 2: 0.5}
|
||||
for n, dc in d.items():
|
||||
assert almost_equal(exact[n], dc)
|
||||
|
||||
def test_degree_centrality_3(self):
|
||||
d = nx.degree_centrality(self.K)
|
||||
exact = {
|
||||
0: 0.444,
|
||||
1: 0.444,
|
||||
2: 0.333,
|
||||
3: 0.667,
|
||||
4: 0.333,
|
||||
5: 0.556,
|
||||
6: 0.556,
|
||||
7: 0.333,
|
||||
8: 0.222,
|
||||
9: 0.111,
|
||||
}
|
||||
for n, dc in d.items():
|
||||
assert almost_equal(exact[n], float(f"{dc:.3f}"))
|
||||
|
||||
def test_degree_centrality_4(self):
|
||||
d = nx.degree_centrality(self.F)
|
||||
names = sorted(self.F.nodes())
|
||||
dcs = [
|
||||
0.071,
|
||||
0.214,
|
||||
0.143,
|
||||
0.214,
|
||||
0.214,
|
||||
0.071,
|
||||
0.286,
|
||||
0.071,
|
||||
0.429,
|
||||
0.071,
|
||||
0.214,
|
||||
0.214,
|
||||
0.143,
|
||||
0.286,
|
||||
0.214,
|
||||
]
|
||||
exact = dict(zip(names, dcs))
|
||||
for n, dc in d.items():
|
||||
assert almost_equal(exact[n], float(f"{dc:.3f}"))
|
||||
|
||||
def test_indegree_centrality(self):
|
||||
d = nx.in_degree_centrality(self.G)
|
||||
exact = {
|
||||
0: 0.0,
|
||||
1: 0.0,
|
||||
2: 0.0,
|
||||
3: 0.0,
|
||||
4: 0.0,
|
||||
5: 0.625,
|
||||
6: 0.125,
|
||||
7: 0.125,
|
||||
8: 0.125,
|
||||
}
|
||||
for n, dc in d.items():
|
||||
assert almost_equal(exact[n], dc)
|
||||
|
||||
def test_outdegree_centrality(self):
|
||||
d = nx.out_degree_centrality(self.G)
|
||||
exact = {
|
||||
0: 0.125,
|
||||
1: 0.125,
|
||||
2: 0.125,
|
||||
3: 0.125,
|
||||
4: 0.125,
|
||||
5: 0.375,
|
||||
6: 0.0,
|
||||
7: 0.0,
|
||||
8: 0.0,
|
||||
}
|
||||
for n, dc in d.items():
|
||||
assert almost_equal(exact[n], dc)
|
||||
|
||||
def test_small_graph_centrality(self):
|
||||
G = nx.empty_graph(create_using=nx.DiGraph)
|
||||
assert {} == nx.degree_centrality(G)
|
||||
assert {} == nx.out_degree_centrality(G)
|
||||
assert {} == nx.in_degree_centrality(G)
|
||||
|
||||
G = nx.empty_graph(1, create_using=nx.DiGraph)
|
||||
assert {0: 1} == nx.degree_centrality(G)
|
||||
assert {0: 1} == nx.out_degree_centrality(G)
|
||||
assert {0: 1} == nx.in_degree_centrality(G)
|
|
@ -0,0 +1,66 @@
|
|||
import networkx as nx
|
||||
|
||||
|
||||
def small_ego_G():
|
||||
"""The sample network from https://arxiv.org/pdf/1310.6753v1.pdf"""
|
||||
edges = [
|
||||
("a", "b"),
|
||||
("a", "c"),
|
||||
("b", "c"),
|
||||
("b", "d"),
|
||||
("b", "e"),
|
||||
("b", "f"),
|
||||
("c", "d"),
|
||||
("c", "f"),
|
||||
("c", "h"),
|
||||
("d", "f"),
|
||||
("e", "f"),
|
||||
("f", "h"),
|
||||
("h", "j"),
|
||||
("h", "k"),
|
||||
("i", "j"),
|
||||
("i", "k"),
|
||||
("j", "k"),
|
||||
("u", "a"),
|
||||
("u", "b"),
|
||||
("u", "c"),
|
||||
("u", "d"),
|
||||
("u", "e"),
|
||||
("u", "f"),
|
||||
("u", "g"),
|
||||
("u", "h"),
|
||||
("u", "i"),
|
||||
("u", "j"),
|
||||
("u", "k"),
|
||||
]
|
||||
G = nx.Graph()
|
||||
G.add_edges_from(edges)
|
||||
|
||||
return G
|
||||
|
||||
|
||||
class TestDispersion:
|
||||
def test_article(self):
|
||||
"""our algorithm matches article's"""
|
||||
G = small_ego_G()
|
||||
disp_uh = nx.dispersion(G, "u", "h", normalized=False)
|
||||
disp_ub = nx.dispersion(G, "u", "b", normalized=False)
|
||||
assert disp_uh == 4
|
||||
assert disp_ub == 1
|
||||
|
||||
def test_results_length(self):
|
||||
"""there is a result for every node"""
|
||||
G = small_ego_G()
|
||||
disp = nx.dispersion(G)
|
||||
disp_Gu = nx.dispersion(G, "u")
|
||||
disp_uv = nx.dispersion(G, "u", "h")
|
||||
assert len(disp) == len(G)
|
||||
assert len(disp_Gu) == len(G) - 1
|
||||
assert type(disp_uv) is float
|
||||
|
||||
def test_impossible_things(self):
|
||||
G = nx.karate_club_graph()
|
||||
disp = nx.dispersion(G)
|
||||
for u in disp:
|
||||
for v in disp[u]:
|
||||
assert disp[u][v] >= 0
|
|
@ -0,0 +1,168 @@
|
|||
import math
|
||||
import pytest
|
||||
|
||||
np = pytest.importorskip("numpy")
|
||||
scipy = pytest.importorskip("scipy")
|
||||
|
||||
|
||||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
class TestEigenvectorCentrality:
|
||||
def test_K5(self):
|
||||
"""Eigenvector centrality: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
b = nx.eigenvector_centrality(G)
|
||||
v = math.sqrt(1 / 5.0)
|
||||
b_answer = dict.fromkeys(G, v)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
nstart = {n: 1 for n in G}
|
||||
b = nx.eigenvector_centrality(G, nstart=nstart)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
b = nx.eigenvector_centrality_numpy(G)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_P3(self):
|
||||
"""Eigenvector centrality: P3"""
|
||||
G = nx.path_graph(3)
|
||||
b_answer = {0: 0.5, 1: 0.7071, 2: 0.5}
|
||||
b = nx.eigenvector_centrality_numpy(G)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=4)
|
||||
b = nx.eigenvector_centrality(G)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=4)
|
||||
|
||||
def test_P3_unweighted(self):
|
||||
"""Eigenvector centrality: P3"""
|
||||
G = nx.path_graph(3)
|
||||
b_answer = {0: 0.5, 1: 0.7071, 2: 0.5}
|
||||
b = nx.eigenvector_centrality_numpy(G, weight=None)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=4)
|
||||
|
||||
def test_maxiter(self):
|
||||
with pytest.raises(nx.PowerIterationFailedConvergence):
|
||||
G = nx.path_graph(3)
|
||||
b = nx.eigenvector_centrality(G, max_iter=0)
|
||||
|
||||
|
||||
class TestEigenvectorCentralityDirected:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
G = nx.DiGraph()
|
||||
|
||||
edges = [
|
||||
(1, 2),
|
||||
(1, 3),
|
||||
(2, 4),
|
||||
(3, 2),
|
||||
(3, 5),
|
||||
(4, 2),
|
||||
(4, 5),
|
||||
(4, 6),
|
||||
(5, 6),
|
||||
(5, 7),
|
||||
(5, 8),
|
||||
(6, 8),
|
||||
(7, 1),
|
||||
(7, 5),
|
||||
(7, 8),
|
||||
(8, 6),
|
||||
(8, 7),
|
||||
]
|
||||
|
||||
G.add_edges_from(edges, weight=2.0)
|
||||
cls.G = G.reverse()
|
||||
cls.G.evc = [
|
||||
0.25368793,
|
||||
0.19576478,
|
||||
0.32817092,
|
||||
0.40430835,
|
||||
0.48199885,
|
||||
0.15724483,
|
||||
0.51346196,
|
||||
0.32475403,
|
||||
]
|
||||
|
||||
H = nx.DiGraph()
|
||||
|
||||
edges = [
|
||||
(1, 2),
|
||||
(1, 3),
|
||||
(2, 4),
|
||||
(3, 2),
|
||||
(3, 5),
|
||||
(4, 2),
|
||||
(4, 5),
|
||||
(4, 6),
|
||||
(5, 6),
|
||||
(5, 7),
|
||||
(5, 8),
|
||||
(6, 8),
|
||||
(7, 1),
|
||||
(7, 5),
|
||||
(7, 8),
|
||||
(8, 6),
|
||||
(8, 7),
|
||||
]
|
||||
|
||||
G.add_edges_from(edges)
|
||||
cls.H = G.reverse()
|
||||
cls.H.evc = [
|
||||
0.25368793,
|
||||
0.19576478,
|
||||
0.32817092,
|
||||
0.40430835,
|
||||
0.48199885,
|
||||
0.15724483,
|
||||
0.51346196,
|
||||
0.32475403,
|
||||
]
|
||||
|
||||
def test_eigenvector_centrality_weighted(self):
|
||||
G = self.G
|
||||
p = nx.eigenvector_centrality(G)
|
||||
for (a, b) in zip(list(p.values()), self.G.evc):
|
||||
assert almost_equal(a, b, places=4)
|
||||
|
||||
def test_eigenvector_centrality_weighted_numpy(self):
|
||||
G = self.G
|
||||
p = nx.eigenvector_centrality_numpy(G)
|
||||
for (a, b) in zip(list(p.values()), self.G.evc):
|
||||
assert almost_equal(a, b)
|
||||
|
||||
def test_eigenvector_centrality_unweighted(self):
|
||||
G = self.H
|
||||
p = nx.eigenvector_centrality(G)
|
||||
for (a, b) in zip(list(p.values()), self.G.evc):
|
||||
assert almost_equal(a, b, places=4)
|
||||
|
||||
def test_eigenvector_centrality_unweighted_numpy(self):
|
||||
G = self.H
|
||||
p = nx.eigenvector_centrality_numpy(G)
|
||||
for (a, b) in zip(list(p.values()), self.G.evc):
|
||||
assert almost_equal(a, b)
|
||||
|
||||
|
||||
class TestEigenvectorCentralityExceptions:
|
||||
def test_multigraph(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
e = nx.eigenvector_centrality(nx.MultiGraph())
|
||||
|
||||
def test_multigraph_numpy(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
e = nx.eigenvector_centrality_numpy(nx.MultiGraph())
|
||||
|
||||
def test_empty(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
e = nx.eigenvector_centrality(nx.Graph())
|
||||
|
||||
def test_empty_numpy(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
e = nx.eigenvector_centrality_numpy(nx.Graph())
|
|
@ -0,0 +1,154 @@
|
|||
"""
|
||||
Tests for Group Centrality Measures
|
||||
"""
|
||||
|
||||
|
||||
import pytest
|
||||
import networkx as nx
|
||||
|
||||
|
||||
class TestGroupBetweennessCentrality:
|
||||
def test_group_betweenness_single_node(self):
|
||||
"""
|
||||
Group betweenness centrality for single node group
|
||||
"""
|
||||
G = nx.path_graph(5)
|
||||
C = [1]
|
||||
b = nx.group_betweenness_centrality(G, C, weight=None, normalized=False)
|
||||
b_answer = 3.0
|
||||
assert b == b_answer
|
||||
|
||||
def test_group_betweenness_normalized(self):
|
||||
"""
|
||||
Group betweenness centrality for group with more than
|
||||
1 node and normalized
|
||||
"""
|
||||
G = nx.path_graph(5)
|
||||
C = [1, 3]
|
||||
b = nx.group_betweenness_centrality(G, C, weight=None, normalized=True)
|
||||
b_answer = 1.0
|
||||
assert b == b_answer
|
||||
|
||||
def test_group_betweenness_value_zero(self):
|
||||
"""
|
||||
Group betweenness centrality value of 0
|
||||
"""
|
||||
G = nx.cycle_graph(6)
|
||||
C = [0, 1, 5]
|
||||
b = nx.group_betweenness_centrality(G, C, weight=None)
|
||||
b_answer = 0.0
|
||||
assert b == b_answer
|
||||
|
||||
def test_group_betweenness_disconnected_graph(self):
|
||||
"""
|
||||
Group betweenness centrality in a disconnected graph
|
||||
"""
|
||||
G = nx.path_graph(5)
|
||||
G.remove_edge(0, 1)
|
||||
C = [1]
|
||||
b = nx.group_betweenness_centrality(G, C, weight=None)
|
||||
b_answer = 0.0
|
||||
assert b == b_answer
|
||||
|
||||
def test_group_betweenness_node_not_in_graph(self):
|
||||
"""
|
||||
Node(s) in C not in graph, raises NodeNotFound exception
|
||||
"""
|
||||
with pytest.raises(nx.NodeNotFound):
|
||||
b = nx.group_betweenness_centrality(nx.path_graph(5), [6, 7, 8])
|
||||
|
||||
|
||||
class TestGroupClosenessCentrality:
|
||||
def test_group_closeness_single_node(self):
|
||||
"""
|
||||
Group closeness centrality for a single node group
|
||||
"""
|
||||
G = nx.path_graph(5)
|
||||
c = nx.group_closeness_centrality(G, [1])
|
||||
c_answer = nx.closeness_centrality(G, 1)
|
||||
assert c == c_answer
|
||||
|
||||
def test_group_closeness_disconnected(self):
|
||||
"""
|
||||
Group closeness centrality for a disconnected graph
|
||||
"""
|
||||
G = nx.Graph()
|
||||
G.add_nodes_from([1, 2, 3, 4])
|
||||
c = nx.group_closeness_centrality(G, [1, 2])
|
||||
c_answer = 0
|
||||
assert c == c_answer
|
||||
|
||||
def test_group_closeness_multiple_node(self):
|
||||
"""
|
||||
Group closeness centrality for a group with more than
|
||||
1 node
|
||||
"""
|
||||
G = nx.path_graph(4)
|
||||
c = nx.group_closeness_centrality(G, [1, 2])
|
||||
c_answer = 1
|
||||
assert c == c_answer
|
||||
|
||||
def test_group_closeness_node_not_in_graph(self):
|
||||
"""
|
||||
Node(s) in S not in graph, raises NodeNotFound exception
|
||||
"""
|
||||
with pytest.raises(nx.NodeNotFound):
|
||||
c = nx.group_closeness_centrality(nx.path_graph(5), [6, 7, 8])
|
||||
|
||||
|
||||
class TestGroupDegreeCentrality:
|
||||
def test_group_degree_centrality_single_node(self):
|
||||
"""
|
||||
Group degree centrality for a single node group
|
||||
"""
|
||||
G = nx.path_graph(4)
|
||||
d = nx.group_degree_centrality(G, [1])
|
||||
d_answer = nx.degree_centrality(G)[1]
|
||||
assert d == d_answer
|
||||
|
||||
def test_group_degree_centrality_multiple_node(self):
|
||||
"""
|
||||
Group degree centrality for group with more than
|
||||
1 node
|
||||
"""
|
||||
G = nx.Graph()
|
||||
G.add_nodes_from([1, 2, 3, 4, 5, 6, 7, 8])
|
||||
G.add_edges_from(
|
||||
[(1, 2), (1, 3), (1, 6), (1, 7), (1, 8), (2, 3), (2, 4), (2, 5)]
|
||||
)
|
||||
d = nx.group_degree_centrality(G, [1, 2])
|
||||
d_answer = 1
|
||||
assert d == d_answer
|
||||
|
||||
def test_group_in_degree_centrality(self):
|
||||
"""
|
||||
Group in-degree centrality in a DiGraph
|
||||
"""
|
||||
G = nx.DiGraph()
|
||||
G.add_nodes_from([1, 2, 3, 4, 5, 6, 7, 8])
|
||||
G.add_edges_from(
|
||||
[(1, 2), (1, 3), (1, 6), (1, 7), (1, 8), (2, 3), (2, 4), (2, 5)]
|
||||
)
|
||||
d = nx.group_in_degree_centrality(G, [1, 2])
|
||||
d_answer = 0
|
||||
assert d == d_answer
|
||||
|
||||
def test_group_out_degree_centrality(self):
|
||||
"""
|
||||
Group out-degree centrality in a DiGraph
|
||||
"""
|
||||
G = nx.DiGraph()
|
||||
G.add_nodes_from([1, 2, 3, 4, 5, 6, 7, 8])
|
||||
G.add_edges_from(
|
||||
[(1, 2), (1, 3), (1, 6), (1, 7), (1, 8), (2, 3), (2, 4), (2, 5)]
|
||||
)
|
||||
d = nx.group_out_degree_centrality(G, [1, 2])
|
||||
d_answer = 1
|
||||
assert d == d_answer
|
||||
|
||||
def test_group_degree_centrality_node_not_in_graph(self):
|
||||
"""
|
||||
Node(s) in S not in graph, raises NetworkXError
|
||||
"""
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
b = nx.group_degree_centrality(nx.path_graph(5), [6, 7, 8])
|
|
@ -0,0 +1,94 @@
|
|||
"""
|
||||
Tests for degree centrality.
|
||||
"""
|
||||
import networkx as nx
|
||||
from networkx.algorithms.centrality import harmonic_centrality
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
class TestClosenessCentrality:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
cls.P3 = nx.path_graph(3)
|
||||
cls.P4 = nx.path_graph(4)
|
||||
cls.K5 = nx.complete_graph(5)
|
||||
|
||||
cls.C4 = nx.cycle_graph(4)
|
||||
cls.C5 = nx.cycle_graph(5)
|
||||
|
||||
cls.T = nx.balanced_tree(r=2, h=2)
|
||||
|
||||
cls.Gb = nx.DiGraph()
|
||||
cls.Gb.add_edges_from([(0, 1), (0, 2), (0, 4), (2, 1), (2, 3), (4, 3)])
|
||||
|
||||
def test_p3_harmonic(self):
|
||||
c = harmonic_centrality(self.P3)
|
||||
d = {0: 1.5, 1: 2, 2: 1.5}
|
||||
for n in sorted(self.P3):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_p4_harmonic(self):
|
||||
c = harmonic_centrality(self.P4)
|
||||
d = {0: 1.8333333, 1: 2.5, 2: 2.5, 3: 1.8333333}
|
||||
for n in sorted(self.P4):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_clique_complete(self):
|
||||
c = harmonic_centrality(self.K5)
|
||||
d = {0: 4, 1: 4, 2: 4, 3: 4, 4: 4}
|
||||
for n in sorted(self.P3):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_cycle_C4(self):
|
||||
c = harmonic_centrality(self.C4)
|
||||
d = {0: 2.5, 1: 2.5, 2: 2.5, 3: 2.5}
|
||||
for n in sorted(self.C4):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_cycle_C5(self):
|
||||
c = harmonic_centrality(self.C5)
|
||||
d = {0: 3, 1: 3, 2: 3, 3: 3, 4: 3, 5: 4}
|
||||
for n in sorted(self.C5):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_bal_tree(self):
|
||||
c = harmonic_centrality(self.T)
|
||||
d = {0: 4.0, 1: 4.1666, 2: 4.1666, 3: 2.8333, 4: 2.8333, 5: 2.8333, 6: 2.8333}
|
||||
for n in sorted(self.T):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_exampleGraph(self):
|
||||
c = harmonic_centrality(self.Gb)
|
||||
d = {0: 0, 1: 2, 2: 1, 3: 2.5, 4: 1}
|
||||
for n in sorted(self.Gb):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_weighted_harmonic(self):
|
||||
XG = nx.DiGraph()
|
||||
XG.add_weighted_edges_from(
|
||||
[
|
||||
("a", "b", 10),
|
||||
("d", "c", 5),
|
||||
("a", "c", 1),
|
||||
("e", "f", 2),
|
||||
("f", "c", 1),
|
||||
("a", "f", 3),
|
||||
]
|
||||
)
|
||||
c = harmonic_centrality(XG, distance="weight")
|
||||
d = {"a": 0, "b": 0.1, "c": 2.533, "d": 0, "e": 0, "f": 0.83333}
|
||||
for n in sorted(XG):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_empty(self):
|
||||
G = nx.DiGraph()
|
||||
c = harmonic_centrality(G, distance="weight")
|
||||
d = {}
|
||||
assert c == d
|
||||
|
||||
def test_singleton(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_node(0)
|
||||
c = harmonic_centrality(G, distance="weight")
|
||||
d = {0: 0}
|
||||
assert c == d
|
|
@ -0,0 +1,355 @@
|
|||
import math
|
||||
|
||||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
import pytest
|
||||
|
||||
|
||||
class TestKatzCentrality:
|
||||
def test_K5(self):
|
||||
"""Katz centrality: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
alpha = 0.1
|
||||
b = nx.katz_centrality(G, alpha)
|
||||
v = math.sqrt(1 / 5.0)
|
||||
b_answer = dict.fromkeys(G, v)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
nstart = {n: 1 for n in G}
|
||||
b = nx.katz_centrality(G, alpha, nstart=nstart)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
|
||||
def test_P3(self):
|
||||
"""Katz centrality: P3"""
|
||||
alpha = 0.1
|
||||
G = nx.path_graph(3)
|
||||
b_answer = {0: 0.5598852584152165, 1: 0.6107839182711449, 2: 0.5598852584152162}
|
||||
b = nx.katz_centrality(G, alpha)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=4)
|
||||
|
||||
def test_maxiter(self):
|
||||
with pytest.raises(nx.PowerIterationFailedConvergence):
|
||||
alpha = 0.1
|
||||
G = nx.path_graph(3)
|
||||
max_iter = 0
|
||||
try:
|
||||
b = nx.katz_centrality(G, alpha, max_iter=max_iter)
|
||||
except nx.NetworkXError as e:
|
||||
assert str(max_iter) in e.args[0], "max_iter value not in error msg"
|
||||
raise # So that the decorater sees the exception.
|
||||
|
||||
def test_beta_as_scalar(self):
|
||||
alpha = 0.1
|
||||
beta = 0.1
|
||||
b_answer = {0: 0.5598852584152165, 1: 0.6107839182711449, 2: 0.5598852584152162}
|
||||
G = nx.path_graph(3)
|
||||
b = nx.katz_centrality(G, alpha, beta)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=4)
|
||||
|
||||
def test_beta_as_dict(self):
|
||||
alpha = 0.1
|
||||
beta = {0: 1.0, 1: 1.0, 2: 1.0}
|
||||
b_answer = {0: 0.5598852584152165, 1: 0.6107839182711449, 2: 0.5598852584152162}
|
||||
G = nx.path_graph(3)
|
||||
b = nx.katz_centrality(G, alpha, beta)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=4)
|
||||
|
||||
def test_multiple_alpha(self):
|
||||
alpha_list = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
|
||||
for alpha in alpha_list:
|
||||
b_answer = {
|
||||
0.1: {
|
||||
0: 0.5598852584152165,
|
||||
1: 0.6107839182711449,
|
||||
2: 0.5598852584152162,
|
||||
},
|
||||
0.2: {
|
||||
0: 0.5454545454545454,
|
||||
1: 0.6363636363636365,
|
||||
2: 0.5454545454545454,
|
||||
},
|
||||
0.3: {
|
||||
0: 0.5333964609104419,
|
||||
1: 0.6564879518897746,
|
||||
2: 0.5333964609104419,
|
||||
},
|
||||
0.4: {
|
||||
0: 0.5232045649263551,
|
||||
1: 0.6726915834767423,
|
||||
2: 0.5232045649263551,
|
||||
},
|
||||
0.5: {
|
||||
0: 0.5144957746691622,
|
||||
1: 0.6859943117075809,
|
||||
2: 0.5144957746691622,
|
||||
},
|
||||
0.6: {
|
||||
0: 0.5069794004195823,
|
||||
1: 0.6970966755769258,
|
||||
2: 0.5069794004195823,
|
||||
},
|
||||
}
|
||||
G = nx.path_graph(3)
|
||||
b = nx.katz_centrality(G, alpha)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[alpha][n], places=4)
|
||||
|
||||
def test_multigraph(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
e = nx.katz_centrality(nx.MultiGraph(), 0.1)
|
||||
|
||||
def test_empty(self):
|
||||
e = nx.katz_centrality(nx.Graph(), 0.1)
|
||||
assert e == {}
|
||||
|
||||
def test_bad_beta(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
G = nx.Graph([(0, 1)])
|
||||
beta = {0: 77}
|
||||
e = nx.katz_centrality(G, 0.1, beta=beta)
|
||||
|
||||
def test_bad_beta_numbe(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
G = nx.Graph([(0, 1)])
|
||||
e = nx.katz_centrality(G, 0.1, beta="foo")
|
||||
|
||||
|
||||
class TestKatzCentralityNumpy:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
global np
|
||||
np = pytest.importorskip("numpy")
|
||||
scipy = pytest.importorskip("scipy")
|
||||
|
||||
def test_K5(self):
|
||||
"""Katz centrality: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
alpha = 0.1
|
||||
b = nx.katz_centrality(G, alpha)
|
||||
v = math.sqrt(1 / 5.0)
|
||||
b_answer = dict.fromkeys(G, v)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
nstart = {n: 1 for n in G}
|
||||
b = nx.eigenvector_centrality_numpy(G)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_P3(self):
|
||||
"""Katz centrality: P3"""
|
||||
alpha = 0.1
|
||||
G = nx.path_graph(3)
|
||||
b_answer = {0: 0.5598852584152165, 1: 0.6107839182711449, 2: 0.5598852584152162}
|
||||
b = nx.katz_centrality_numpy(G, alpha)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=4)
|
||||
|
||||
def test_beta_as_scalar(self):
|
||||
alpha = 0.1
|
||||
beta = 0.1
|
||||
b_answer = {0: 0.5598852584152165, 1: 0.6107839182711449, 2: 0.5598852584152162}
|
||||
G = nx.path_graph(3)
|
||||
b = nx.katz_centrality_numpy(G, alpha, beta)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=4)
|
||||
|
||||
def test_beta_as_dict(self):
|
||||
alpha = 0.1
|
||||
beta = {0: 1.0, 1: 1.0, 2: 1.0}
|
||||
b_answer = {0: 0.5598852584152165, 1: 0.6107839182711449, 2: 0.5598852584152162}
|
||||
G = nx.path_graph(3)
|
||||
b = nx.katz_centrality_numpy(G, alpha, beta)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=4)
|
||||
|
||||
def test_multiple_alpha(self):
|
||||
alpha_list = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
|
||||
for alpha in alpha_list:
|
||||
b_answer = {
|
||||
0.1: {
|
||||
0: 0.5598852584152165,
|
||||
1: 0.6107839182711449,
|
||||
2: 0.5598852584152162,
|
||||
},
|
||||
0.2: {
|
||||
0: 0.5454545454545454,
|
||||
1: 0.6363636363636365,
|
||||
2: 0.5454545454545454,
|
||||
},
|
||||
0.3: {
|
||||
0: 0.5333964609104419,
|
||||
1: 0.6564879518897746,
|
||||
2: 0.5333964609104419,
|
||||
},
|
||||
0.4: {
|
||||
0: 0.5232045649263551,
|
||||
1: 0.6726915834767423,
|
||||
2: 0.5232045649263551,
|
||||
},
|
||||
0.5: {
|
||||
0: 0.5144957746691622,
|
||||
1: 0.6859943117075809,
|
||||
2: 0.5144957746691622,
|
||||
},
|
||||
0.6: {
|
||||
0: 0.5069794004195823,
|
||||
1: 0.6970966755769258,
|
||||
2: 0.5069794004195823,
|
||||
},
|
||||
}
|
||||
G = nx.path_graph(3)
|
||||
b = nx.katz_centrality_numpy(G, alpha)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[alpha][n], places=4)
|
||||
|
||||
def test_multigraph(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
e = nx.katz_centrality(nx.MultiGraph(), 0.1)
|
||||
|
||||
def test_empty(self):
|
||||
e = nx.katz_centrality(nx.Graph(), 0.1)
|
||||
assert e == {}
|
||||
|
||||
def test_bad_beta(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
G = nx.Graph([(0, 1)])
|
||||
beta = {0: 77}
|
||||
e = nx.katz_centrality_numpy(G, 0.1, beta=beta)
|
||||
|
||||
def test_bad_beta_numbe(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
G = nx.Graph([(0, 1)])
|
||||
e = nx.katz_centrality_numpy(G, 0.1, beta="foo")
|
||||
|
||||
def test_K5_unweighted(self):
|
||||
"""Katz centrality: K5"""
|
||||
G = nx.complete_graph(5)
|
||||
alpha = 0.1
|
||||
b = nx.katz_centrality(G, alpha, weight=None)
|
||||
v = math.sqrt(1 / 5.0)
|
||||
b_answer = dict.fromkeys(G, v)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n])
|
||||
nstart = {n: 1 for n in G}
|
||||
b = nx.eigenvector_centrality_numpy(G, weight=None)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=3)
|
||||
|
||||
def test_P3_unweighted(self):
|
||||
"""Katz centrality: P3"""
|
||||
alpha = 0.1
|
||||
G = nx.path_graph(3)
|
||||
b_answer = {0: 0.5598852584152165, 1: 0.6107839182711449, 2: 0.5598852584152162}
|
||||
b = nx.katz_centrality_numpy(G, alpha, weight=None)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=4)
|
||||
|
||||
|
||||
class TestKatzCentralityDirected:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
G = nx.DiGraph()
|
||||
edges = [
|
||||
(1, 2),
|
||||
(1, 3),
|
||||
(2, 4),
|
||||
(3, 2),
|
||||
(3, 5),
|
||||
(4, 2),
|
||||
(4, 5),
|
||||
(4, 6),
|
||||
(5, 6),
|
||||
(5, 7),
|
||||
(5, 8),
|
||||
(6, 8),
|
||||
(7, 1),
|
||||
(7, 5),
|
||||
(7, 8),
|
||||
(8, 6),
|
||||
(8, 7),
|
||||
]
|
||||
G.add_edges_from(edges, weight=2.0)
|
||||
cls.G = G.reverse()
|
||||
cls.G.alpha = 0.1
|
||||
cls.G.evc = [
|
||||
0.3289589783189635,
|
||||
0.2832077296243516,
|
||||
0.3425906003685471,
|
||||
0.3970420865198392,
|
||||
0.41074871061646284,
|
||||
0.272257430756461,
|
||||
0.4201989685435462,
|
||||
0.34229059218038554,
|
||||
]
|
||||
|
||||
H = nx.DiGraph(edges)
|
||||
cls.H = G.reverse()
|
||||
cls.H.alpha = 0.1
|
||||
cls.H.evc = [
|
||||
0.3289589783189635,
|
||||
0.2832077296243516,
|
||||
0.3425906003685471,
|
||||
0.3970420865198392,
|
||||
0.41074871061646284,
|
||||
0.272257430756461,
|
||||
0.4201989685435462,
|
||||
0.34229059218038554,
|
||||
]
|
||||
|
||||
def test_katz_centrality_weighted(self):
|
||||
G = self.G
|
||||
alpha = self.G.alpha
|
||||
p = nx.katz_centrality(G, alpha, weight="weight")
|
||||
for (a, b) in zip(list(p.values()), self.G.evc):
|
||||
assert almost_equal(a, b)
|
||||
|
||||
def test_katz_centrality_unweighted(self):
|
||||
H = self.H
|
||||
alpha = self.H.alpha
|
||||
p = nx.katz_centrality(H, alpha, weight="weight")
|
||||
for (a, b) in zip(list(p.values()), self.H.evc):
|
||||
assert almost_equal(a, b)
|
||||
|
||||
|
||||
class TestKatzCentralityDirectedNumpy(TestKatzCentralityDirected):
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
global np
|
||||
np = pytest.importorskip("numpy")
|
||||
scipy = pytest.importorskip("scipy")
|
||||
|
||||
def test_katz_centrality_weighted(self):
|
||||
G = self.G
|
||||
alpha = self.G.alpha
|
||||
p = nx.katz_centrality_numpy(G, alpha, weight="weight")
|
||||
for (a, b) in zip(list(p.values()), self.G.evc):
|
||||
assert almost_equal(a, b)
|
||||
|
||||
def test_katz_centrality_unweighted(self):
|
||||
H = self.H
|
||||
alpha = self.H.alpha
|
||||
p = nx.katz_centrality_numpy(H, alpha, weight="weight")
|
||||
for (a, b) in zip(list(p.values()), self.H.evc):
|
||||
assert almost_equal(a, b)
|
||||
|
||||
|
||||
class TestKatzEigenvectorVKatz:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
global np
|
||||
global eigvals
|
||||
np = pytest.importorskip("numpy")
|
||||
scipy = pytest.importorskip("scipy")
|
||||
from numpy.linalg import eigvals
|
||||
|
||||
def test_eigenvector_v_katz_random(self):
|
||||
G = nx.gnp_random_graph(10, 0.5, seed=1234)
|
||||
l = float(max(eigvals(nx.adjacency_matrix(G).todense())))
|
||||
e = nx.eigenvector_centrality_numpy(G)
|
||||
k = nx.katz_centrality_numpy(G, 1.0 / l)
|
||||
for n in G:
|
||||
assert almost_equal(e[n], k[n])
|
|
@ -0,0 +1,336 @@
|
|||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
class TestLoadCentrality:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
|
||||
G = nx.Graph()
|
||||
G.add_edge(0, 1, weight=3)
|
||||
G.add_edge(0, 2, weight=2)
|
||||
G.add_edge(0, 3, weight=6)
|
||||
G.add_edge(0, 4, weight=4)
|
||||
G.add_edge(1, 3, weight=5)
|
||||
G.add_edge(1, 5, weight=5)
|
||||
G.add_edge(2, 4, weight=1)
|
||||
G.add_edge(3, 4, weight=2)
|
||||
G.add_edge(3, 5, weight=1)
|
||||
G.add_edge(4, 5, weight=4)
|
||||
cls.G = G
|
||||
cls.exact_weighted = {0: 4.0, 1: 0.0, 2: 8.0, 3: 6.0, 4: 8.0, 5: 0.0}
|
||||
cls.K = nx.krackhardt_kite_graph()
|
||||
cls.P3 = nx.path_graph(3)
|
||||
cls.P4 = nx.path_graph(4)
|
||||
cls.K5 = nx.complete_graph(5)
|
||||
|
||||
cls.C4 = nx.cycle_graph(4)
|
||||
cls.T = nx.balanced_tree(r=2, h=2)
|
||||
cls.Gb = nx.Graph()
|
||||
cls.Gb.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (4, 5), (3, 5)])
|
||||
cls.F = nx.florentine_families_graph()
|
||||
cls.LM = nx.les_miserables_graph()
|
||||
cls.D = nx.cycle_graph(3, create_using=nx.DiGraph())
|
||||
cls.D.add_edges_from([(3, 0), (4, 3)])
|
||||
|
||||
def test_not_strongly_connected(self):
|
||||
b = nx.load_centrality(self.D)
|
||||
result = {0: 5.0 / 12, 1: 1.0 / 4, 2: 1.0 / 12, 3: 1.0 / 4, 4: 0.000}
|
||||
for n in sorted(self.D):
|
||||
assert almost_equal(result[n], b[n], places=3)
|
||||
assert almost_equal(result[n], nx.load_centrality(self.D, n), places=3)
|
||||
|
||||
def test_weighted_load(self):
|
||||
b = nx.load_centrality(self.G, weight="weight", normalized=False)
|
||||
for n in sorted(self.G):
|
||||
assert b[n] == self.exact_weighted[n]
|
||||
|
||||
def test_k5_load(self):
|
||||
G = self.K5
|
||||
c = nx.load_centrality(G)
|
||||
d = {0: 0.000, 1: 0.000, 2: 0.000, 3: 0.000, 4: 0.000}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_p3_load(self):
|
||||
G = self.P3
|
||||
c = nx.load_centrality(G)
|
||||
d = {0: 0.000, 1: 1.000, 2: 0.000}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
c = nx.load_centrality(G, v=1)
|
||||
assert almost_equal(c, 1.0)
|
||||
c = nx.load_centrality(G, v=1, normalized=True)
|
||||
assert almost_equal(c, 1.0)
|
||||
|
||||
def test_p2_load(self):
|
||||
G = nx.path_graph(2)
|
||||
c = nx.load_centrality(G)
|
||||
d = {0: 0.000, 1: 0.000}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_krackhardt_load(self):
|
||||
G = self.K
|
||||
c = nx.load_centrality(G)
|
||||
d = {
|
||||
0: 0.023,
|
||||
1: 0.023,
|
||||
2: 0.000,
|
||||
3: 0.102,
|
||||
4: 0.000,
|
||||
5: 0.231,
|
||||
6: 0.231,
|
||||
7: 0.389,
|
||||
8: 0.222,
|
||||
9: 0.000,
|
||||
}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_florentine_families_load(self):
|
||||
G = self.F
|
||||
c = nx.load_centrality(G)
|
||||
d = {
|
||||
"Acciaiuoli": 0.000,
|
||||
"Albizzi": 0.211,
|
||||
"Barbadori": 0.093,
|
||||
"Bischeri": 0.104,
|
||||
"Castellani": 0.055,
|
||||
"Ginori": 0.000,
|
||||
"Guadagni": 0.251,
|
||||
"Lamberteschi": 0.000,
|
||||
"Medici": 0.522,
|
||||
"Pazzi": 0.000,
|
||||
"Peruzzi": 0.022,
|
||||
"Ridolfi": 0.117,
|
||||
"Salviati": 0.143,
|
||||
"Strozzi": 0.106,
|
||||
"Tornabuoni": 0.090,
|
||||
}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_les_miserables_load(self):
|
||||
G = self.LM
|
||||
c = nx.load_centrality(G)
|
||||
d = {
|
||||
"Napoleon": 0.000,
|
||||
"Myriel": 0.177,
|
||||
"MlleBaptistine": 0.000,
|
||||
"MmeMagloire": 0.000,
|
||||
"CountessDeLo": 0.000,
|
||||
"Geborand": 0.000,
|
||||
"Champtercier": 0.000,
|
||||
"Cravatte": 0.000,
|
||||
"Count": 0.000,
|
||||
"OldMan": 0.000,
|
||||
"Valjean": 0.567,
|
||||
"Labarre": 0.000,
|
||||
"Marguerite": 0.000,
|
||||
"MmeDeR": 0.000,
|
||||
"Isabeau": 0.000,
|
||||
"Gervais": 0.000,
|
||||
"Listolier": 0.000,
|
||||
"Tholomyes": 0.043,
|
||||
"Fameuil": 0.000,
|
||||
"Blacheville": 0.000,
|
||||
"Favourite": 0.000,
|
||||
"Dahlia": 0.000,
|
||||
"Zephine": 0.000,
|
||||
"Fantine": 0.128,
|
||||
"MmeThenardier": 0.029,
|
||||
"Thenardier": 0.075,
|
||||
"Cosette": 0.024,
|
||||
"Javert": 0.054,
|
||||
"Fauchelevent": 0.026,
|
||||
"Bamatabois": 0.008,
|
||||
"Perpetue": 0.000,
|
||||
"Simplice": 0.009,
|
||||
"Scaufflaire": 0.000,
|
||||
"Woman1": 0.000,
|
||||
"Judge": 0.000,
|
||||
"Champmathieu": 0.000,
|
||||
"Brevet": 0.000,
|
||||
"Chenildieu": 0.000,
|
||||
"Cochepaille": 0.000,
|
||||
"Pontmercy": 0.007,
|
||||
"Boulatruelle": 0.000,
|
||||
"Eponine": 0.012,
|
||||
"Anzelma": 0.000,
|
||||
"Woman2": 0.000,
|
||||
"MotherInnocent": 0.000,
|
||||
"Gribier": 0.000,
|
||||
"MmeBurgon": 0.026,
|
||||
"Jondrette": 0.000,
|
||||
"Gavroche": 0.164,
|
||||
"Gillenormand": 0.021,
|
||||
"Magnon": 0.000,
|
||||
"MlleGillenormand": 0.047,
|
||||
"MmePontmercy": 0.000,
|
||||
"MlleVaubois": 0.000,
|
||||
"LtGillenormand": 0.000,
|
||||
"Marius": 0.133,
|
||||
"BaronessT": 0.000,
|
||||
"Mabeuf": 0.028,
|
||||
"Enjolras": 0.041,
|
||||
"Combeferre": 0.001,
|
||||
"Prouvaire": 0.000,
|
||||
"Feuilly": 0.001,
|
||||
"Courfeyrac": 0.006,
|
||||
"Bahorel": 0.002,
|
||||
"Bossuet": 0.032,
|
||||
"Joly": 0.002,
|
||||
"Grantaire": 0.000,
|
||||
"MotherPlutarch": 0.000,
|
||||
"Gueulemer": 0.005,
|
||||
"Babet": 0.005,
|
||||
"Claquesous": 0.005,
|
||||
"Montparnasse": 0.004,
|
||||
"Toussaint": 0.000,
|
||||
"Child1": 0.000,
|
||||
"Child2": 0.000,
|
||||
"Brujon": 0.000,
|
||||
"MmeHucheloup": 0.000,
|
||||
}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_unnormalized_k5_load(self):
|
||||
G = self.K5
|
||||
c = nx.load_centrality(G, normalized=False)
|
||||
d = {0: 0.000, 1: 0.000, 2: 0.000, 3: 0.000, 4: 0.000}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_unnormalized_p3_load(self):
|
||||
G = self.P3
|
||||
c = nx.load_centrality(G, normalized=False)
|
||||
d = {0: 0.000, 1: 2.000, 2: 0.000}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_unnormalized_krackhardt_load(self):
|
||||
G = self.K
|
||||
c = nx.load_centrality(G, normalized=False)
|
||||
d = {
|
||||
0: 1.667,
|
||||
1: 1.667,
|
||||
2: 0.000,
|
||||
3: 7.333,
|
||||
4: 0.000,
|
||||
5: 16.667,
|
||||
6: 16.667,
|
||||
7: 28.000,
|
||||
8: 16.000,
|
||||
9: 0.000,
|
||||
}
|
||||
|
||||
for n in sorted(G):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_unnormalized_florentine_families_load(self):
|
||||
G = self.F
|
||||
c = nx.load_centrality(G, normalized=False)
|
||||
|
||||
d = {
|
||||
"Acciaiuoli": 0.000,
|
||||
"Albizzi": 38.333,
|
||||
"Barbadori": 17.000,
|
||||
"Bischeri": 19.000,
|
||||
"Castellani": 10.000,
|
||||
"Ginori": 0.000,
|
||||
"Guadagni": 45.667,
|
||||
"Lamberteschi": 0.000,
|
||||
"Medici": 95.000,
|
||||
"Pazzi": 0.000,
|
||||
"Peruzzi": 4.000,
|
||||
"Ridolfi": 21.333,
|
||||
"Salviati": 26.000,
|
||||
"Strozzi": 19.333,
|
||||
"Tornabuoni": 16.333,
|
||||
}
|
||||
for n in sorted(G):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_load_betweenness_difference(self):
|
||||
# Difference Between Load and Betweenness
|
||||
# --------------------------------------- The smallest graph
|
||||
# that shows the difference between load and betweenness is
|
||||
# G=ladder_graph(3) (Graph B below)
|
||||
|
||||
# Graph A and B are from Tao Zhou, Jian-Guo Liu, Bing-Hong
|
||||
# Wang: Comment on "Scientific collaboration
|
||||
# networks. II. Shortest paths, weighted networks, and
|
||||
# centrality". https://arxiv.org/pdf/physics/0511084
|
||||
|
||||
# Notice that unlike here, their calculation adds to 1 to the
|
||||
# betweennes of every node i for every path from i to every
|
||||
# other node. This is exactly what it should be, based on
|
||||
# Eqn. (1) in their paper: the eqn is B(v) = \sum_{s\neq t,
|
||||
# s\neq v}{\frac{\sigma_{st}(v)}{\sigma_{st}}}, therefore,
|
||||
# they allow v to be the target node.
|
||||
|
||||
# We follow Brandes 2001, who follows Freeman 1977 that make
|
||||
# the sum for betweenness of v exclude paths where v is either
|
||||
# the source or target node. To agree with their numbers, we
|
||||
# must additionally, remove edge (4,8) from the graph, see AC
|
||||
# example following (there is a mistake in the figure in their
|
||||
# paper - personal communication).
|
||||
|
||||
# A = nx.Graph()
|
||||
# A.add_edges_from([(0,1), (1,2), (1,3), (2,4),
|
||||
# (3,5), (4,6), (4,7), (4,8),
|
||||
# (5,8), (6,9), (7,9), (8,9)])
|
||||
B = nx.Graph() # ladder_graph(3)
|
||||
B.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (4, 5), (3, 5)])
|
||||
c = nx.load_centrality(B, normalized=False)
|
||||
d = {0: 1.750, 1: 1.750, 2: 6.500, 3: 6.500, 4: 1.750, 5: 1.750}
|
||||
for n in sorted(B):
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_c4_edge_load(self):
|
||||
G = self.C4
|
||||
c = nx.edge_load_centrality(G)
|
||||
d = {(0, 1): 6.000, (0, 3): 6.000, (1, 2): 6.000, (2, 3): 6.000}
|
||||
for n in G.edges():
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_p4_edge_load(self):
|
||||
G = self.P4
|
||||
c = nx.edge_load_centrality(G)
|
||||
d = {(0, 1): 6.000, (1, 2): 8.000, (2, 3): 6.000}
|
||||
for n in G.edges():
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_k5_edge_load(self):
|
||||
G = self.K5
|
||||
c = nx.edge_load_centrality(G)
|
||||
d = {
|
||||
(0, 1): 5.000,
|
||||
(0, 2): 5.000,
|
||||
(0, 3): 5.000,
|
||||
(0, 4): 5.000,
|
||||
(1, 2): 5.000,
|
||||
(1, 3): 5.000,
|
||||
(1, 4): 5.000,
|
||||
(2, 3): 5.000,
|
||||
(2, 4): 5.000,
|
||||
(3, 4): 5.000,
|
||||
}
|
||||
for n in G.edges():
|
||||
assert almost_equal(c[n], d[n], places=3)
|
||||
|
||||
def test_tree_edge_load(self):
|
||||
G = self.T
|
||||
c = nx.edge_load_centrality(G)
|
||||
d = {
|
||||
(0, 1): 24.000,
|
||||
(0, 2): 24.000,
|
||||
(1, 3): 12.000,
|
||||
(1, 4): 12.000,
|
||||
(2, 5): 12.000,
|
||||
(2, 6): 12.000,
|
||||
}
|
||||
for n in G.edges():
|
||||
assert almost_equal(c[n], d[n], places=3)
|
|
@ -0,0 +1,81 @@
|
|||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
def example1a_G():
|
||||
G = nx.Graph()
|
||||
G.add_node(1, percolation=0.1)
|
||||
G.add_node(2, percolation=0.2)
|
||||
G.add_node(3, percolation=0.2)
|
||||
G.add_node(4, percolation=0.2)
|
||||
G.add_node(5, percolation=0.3)
|
||||
G.add_node(6, percolation=0.2)
|
||||
G.add_node(7, percolation=0.5)
|
||||
G.add_node(8, percolation=0.5)
|
||||
G.add_edges_from([(1, 4), (2, 4), (3, 4), (4, 5), (5, 6), (6, 7), (6, 8)])
|
||||
return G
|
||||
|
||||
|
||||
def example1b_G():
|
||||
G = nx.Graph()
|
||||
G.add_node(1, percolation=0.3)
|
||||
G.add_node(2, percolation=0.5)
|
||||
G.add_node(3, percolation=0.5)
|
||||
G.add_node(4, percolation=0.2)
|
||||
G.add_node(5, percolation=0.3)
|
||||
G.add_node(6, percolation=0.2)
|
||||
G.add_node(7, percolation=0.1)
|
||||
G.add_node(8, percolation=0.1)
|
||||
G.add_edges_from([(1, 4), (2, 4), (3, 4), (4, 5), (5, 6), (6, 7), (6, 8)])
|
||||
return G
|
||||
|
||||
|
||||
class TestPercolationCentrality:
|
||||
def test_percolation_example1a(self):
|
||||
"""percolation centrality: example 1a"""
|
||||
G = example1a_G()
|
||||
p = nx.percolation_centrality(G)
|
||||
p_answer = {4: 0.625, 6: 0.667}
|
||||
for n in p_answer:
|
||||
assert almost_equal(p[n], p_answer[n], places=3)
|
||||
|
||||
def test_percolation_example1b(self):
|
||||
"""percolation centrality: example 1a"""
|
||||
G = example1b_G()
|
||||
p = nx.percolation_centrality(G)
|
||||
p_answer = {4: 0.825, 6: 0.4}
|
||||
for n in p_answer:
|
||||
assert almost_equal(p[n], p_answer[n], places=3)
|
||||
|
||||
def test_converge_to_betweenness(self):
|
||||
"""percolation centrality: should converge to betweenness
|
||||
centrality when all nodes are percolated the same"""
|
||||
# taken from betweenness test test_florentine_families_graph
|
||||
G = nx.florentine_families_graph()
|
||||
b_answer = {
|
||||
"Acciaiuoli": 0.000,
|
||||
"Albizzi": 0.212,
|
||||
"Barbadori": 0.093,
|
||||
"Bischeri": 0.104,
|
||||
"Castellani": 0.055,
|
||||
"Ginori": 0.000,
|
||||
"Guadagni": 0.255,
|
||||
"Lamberteschi": 0.000,
|
||||
"Medici": 0.522,
|
||||
"Pazzi": 0.000,
|
||||
"Peruzzi": 0.022,
|
||||
"Ridolfi": 0.114,
|
||||
"Salviati": 0.143,
|
||||
"Strozzi": 0.103,
|
||||
"Tornabuoni": 0.092,
|
||||
}
|
||||
|
||||
p_states = {k: 1.0 for k, v in b_answer.items()}
|
||||
p_answer = nx.percolation_centrality(G, states=p_states)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(p_answer[n], b_answer[n], places=3)
|
||||
|
||||
p_states = {k: 0.3 for k, v in b_answer.items()}
|
||||
p_answer = nx.percolation_centrality(G, states=p_states)
|
||||
for n in sorted(G):
|
||||
assert almost_equal(p_answer[n], b_answer[n], places=3)
|
|
@ -0,0 +1,110 @@
|
|||
"""Unit tests for the :mod:`networkx.algorithms.centrality.reaching` module."""
|
||||
import pytest
|
||||
|
||||
from networkx import nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
class TestGlobalReachingCentrality:
|
||||
"""Unit tests for the global reaching centrality function."""
|
||||
|
||||
def test_non_positive_weights(self):
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
G = nx.DiGraph()
|
||||
nx.global_reaching_centrality(G, weight="weight")
|
||||
|
||||
def test_negatively_weighted(self):
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
G = nx.Graph()
|
||||
G.add_weighted_edges_from([(0, 1, -2), (1, 2, +1)])
|
||||
nx.global_reaching_centrality(G, weight="weight")
|
||||
|
||||
def test_directed_star(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_weighted_edges_from([(1, 2, 0.5), (1, 3, 0.5)])
|
||||
grc = nx.global_reaching_centrality
|
||||
assert grc(G, normalized=False, weight="weight") == 0.5
|
||||
assert grc(G) == 1
|
||||
|
||||
def test_undirected_unweighted_star(self):
|
||||
G = nx.star_graph(2)
|
||||
grc = nx.global_reaching_centrality
|
||||
assert grc(G, normalized=False, weight=None) == 0.25
|
||||
|
||||
def test_undirected_weighted_star(self):
|
||||
G = nx.Graph()
|
||||
G.add_weighted_edges_from([(1, 2, 1), (1, 3, 2)])
|
||||
grc = nx.global_reaching_centrality
|
||||
assert grc(G, normalized=False, weight="weight") == 0.375
|
||||
|
||||
def test_cycle_directed_unweighted(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_edge(1, 2)
|
||||
G.add_edge(2, 1)
|
||||
assert nx.global_reaching_centrality(G, weight=None) == 0
|
||||
|
||||
def test_cycle_undirected_unweighted(self):
|
||||
G = nx.Graph()
|
||||
G.add_edge(1, 2)
|
||||
assert nx.global_reaching_centrality(G, weight=None) == 0
|
||||
|
||||
def test_cycle_directed_weighted(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_weighted_edges_from([(1, 2, 1), (2, 1, 1)])
|
||||
assert nx.global_reaching_centrality(G) == 0
|
||||
|
||||
def test_cycle_undirected_weighted(self):
|
||||
G = nx.Graph()
|
||||
G.add_edge(1, 2, weight=1)
|
||||
grc = nx.global_reaching_centrality
|
||||
assert grc(G, normalized=False) == 0
|
||||
|
||||
def test_directed_weighted(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_edge("A", "B", weight=5)
|
||||
G.add_edge("B", "C", weight=1)
|
||||
G.add_edge("B", "D", weight=0.25)
|
||||
G.add_edge("D", "E", weight=1)
|
||||
|
||||
denom = len(G) - 1
|
||||
A_local = sum([5, 3, 2.625, 2.0833333333333]) / denom
|
||||
B_local = sum([1, 0.25, 0.625]) / denom
|
||||
C_local = 0
|
||||
D_local = sum([1]) / denom
|
||||
E_local = 0
|
||||
|
||||
local_reach_ctrs = [A_local, C_local, B_local, D_local, E_local]
|
||||
max_local = max(local_reach_ctrs)
|
||||
expected = sum(max_local - lrc for lrc in local_reach_ctrs) / denom
|
||||
grc = nx.global_reaching_centrality
|
||||
actual = grc(G, normalized=False, weight="weight")
|
||||
assert almost_equal(expected, actual, places=7)
|
||||
|
||||
|
||||
class TestLocalReachingCentrality:
|
||||
"""Unit tests for the local reaching centrality function."""
|
||||
|
||||
def test_non_positive_weights(self):
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
G = nx.DiGraph()
|
||||
G.add_weighted_edges_from([(0, 1, 0)])
|
||||
nx.local_reaching_centrality(G, 0, weight="weight")
|
||||
|
||||
def test_negatively_weighted(self):
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
G = nx.Graph()
|
||||
G.add_weighted_edges_from([(0, 1, -2), (1, 2, +1)])
|
||||
nx.local_reaching_centrality(G, 0, weight="weight")
|
||||
|
||||
def test_undirected_unweighted_star(self):
|
||||
G = nx.star_graph(2)
|
||||
grc = nx.local_reaching_centrality
|
||||
assert grc(G, 1, weight=None, normalized=False) == 0.75
|
||||
|
||||
def test_undirected_weighted_star(self):
|
||||
G = nx.Graph()
|
||||
G.add_weighted_edges_from([(1, 2, 1), (1, 3, 2)])
|
||||
centrality = nx.local_reaching_centrality(
|
||||
G, 1, normalized=False, weight="weight"
|
||||
)
|
||||
assert centrality == 1.5
|
|
@ -0,0 +1,68 @@
|
|||
"""
|
||||
Tests for second order centrality.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
np = pytest.importorskip("numpy")
|
||||
scipy = pytest.importorskip("scipy")
|
||||
|
||||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
class TestSecondOrderCentrality:
|
||||
def test_empty(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
G = nx.empty_graph()
|
||||
nx.second_order_centrality(G)
|
||||
|
||||
def test_non_connected(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
G = nx.Graph()
|
||||
G.add_node(0)
|
||||
G.add_node(1)
|
||||
nx.second_order_centrality(G)
|
||||
|
||||
def test_non_negative_edge_weights(self):
|
||||
with pytest.raises(nx.NetworkXException):
|
||||
G = nx.path_graph(2)
|
||||
G.add_edge(0, 1, weight=-1)
|
||||
nx.second_order_centrality(G)
|
||||
|
||||
def test_one_node_graph(self):
|
||||
"""Second order centrality: single node"""
|
||||
G = nx.Graph()
|
||||
G.add_node(0)
|
||||
G.add_edge(0, 0)
|
||||
assert nx.second_order_centrality(G)[0] == 0
|
||||
|
||||
def test_P3(self):
|
||||
"""Second order centrality: line graph, as defined in paper"""
|
||||
G = nx.path_graph(3)
|
||||
b_answer = {0: 3.741, 1: 1.414, 2: 3.741}
|
||||
|
||||
b = nx.second_order_centrality(G)
|
||||
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=2)
|
||||
|
||||
def test_K3(self):
|
||||
"""Second order centrality: complete graph, as defined in paper"""
|
||||
G = nx.complete_graph(3)
|
||||
b_answer = {0: 1.414, 1: 1.414, 2: 1.414}
|
||||
|
||||
b = nx.second_order_centrality(G)
|
||||
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=2)
|
||||
|
||||
def test_ring_graph(self):
|
||||
"""Second order centrality: ring graph, as defined in paper"""
|
||||
G = nx.cycle_graph(5)
|
||||
b_answer = {0: 4.472, 1: 4.472, 2: 4.472, 3: 4.472, 4: 4.472}
|
||||
|
||||
b = nx.second_order_centrality(G)
|
||||
|
||||
for n in sorted(G):
|
||||
assert almost_equal(b[n], b_answer[n], places=2)
|
|
@ -0,0 +1,92 @@
|
|||
import pytest
|
||||
|
||||
numpy = pytest.importorskip("numpy")
|
||||
scipy = pytest.importorskip("scipy")
|
||||
|
||||
import networkx as nx
|
||||
from networkx.algorithms.centrality.subgraph_alg import (
|
||||
estrada_index,
|
||||
communicability_betweenness_centrality,
|
||||
subgraph_centrality,
|
||||
subgraph_centrality_exp,
|
||||
)
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
class TestSubgraph:
|
||||
def test_subgraph_centrality(self):
|
||||
answer = {0: 1.5430806348152433, 1: 1.5430806348152433}
|
||||
result = subgraph_centrality(nx.path_graph(2))
|
||||
for k, v in result.items():
|
||||
assert almost_equal(answer[k], result[k], places=7)
|
||||
|
||||
answer1 = {
|
||||
"1": 1.6445956054135658,
|
||||
"Albert": 2.4368257358712189,
|
||||
"Aric": 2.4368257358712193,
|
||||
"Dan": 3.1306328496328168,
|
||||
"Franck": 2.3876142275231915,
|
||||
}
|
||||
G1 = nx.Graph(
|
||||
[
|
||||
("Franck", "Aric"),
|
||||
("Aric", "Dan"),
|
||||
("Dan", "Albert"),
|
||||
("Albert", "Franck"),
|
||||
("Dan", "1"),
|
||||
("Franck", "Albert"),
|
||||
]
|
||||
)
|
||||
result1 = subgraph_centrality(G1)
|
||||
for k, v in result1.items():
|
||||
assert almost_equal(answer1[k], result1[k], places=7)
|
||||
result1 = subgraph_centrality_exp(G1)
|
||||
for k, v in result1.items():
|
||||
assert almost_equal(answer1[k], result1[k], places=7)
|
||||
|
||||
def test_subgraph_centrality_big_graph(self):
|
||||
g199 = nx.complete_graph(199)
|
||||
g200 = nx.complete_graph(200)
|
||||
|
||||
comm199 = nx.subgraph_centrality(g199)
|
||||
comm199_exp = nx.subgraph_centrality_exp(g199)
|
||||
|
||||
comm200 = nx.subgraph_centrality(g200)
|
||||
comm200_exp = nx.subgraph_centrality_exp(g200)
|
||||
|
||||
def test_communicability_betweenness_centrality(self):
|
||||
answer = {
|
||||
0: 0.07017447951484615,
|
||||
1: 0.71565598701107991,
|
||||
2: 0.71565598701107991,
|
||||
3: 0.07017447951484615,
|
||||
}
|
||||
result = communicability_betweenness_centrality(nx.path_graph(4))
|
||||
for k, v in result.items():
|
||||
assert almost_equal(answer[k], result[k], places=7)
|
||||
|
||||
answer1 = {
|
||||
"1": 0.060039074193949521,
|
||||
"Albert": 0.315470761661372,
|
||||
"Aric": 0.31547076166137211,
|
||||
"Dan": 0.68297778678316201,
|
||||
"Franck": 0.21977926617449497,
|
||||
}
|
||||
G1 = nx.Graph(
|
||||
[
|
||||
("Franck", "Aric"),
|
||||
("Aric", "Dan"),
|
||||
("Dan", "Albert"),
|
||||
("Albert", "Franck"),
|
||||
("Dan", "1"),
|
||||
("Franck", "Albert"),
|
||||
]
|
||||
)
|
||||
result1 = communicability_betweenness_centrality(G1)
|
||||
for k, v in result1.items():
|
||||
assert almost_equal(answer1[k], result1[k], places=7)
|
||||
|
||||
def test_estrada_index(self):
|
||||
answer = 1041.2470334195475
|
||||
result = estrada_index(nx.karate_club_graph())
|
||||
assert almost_equal(answer, result, places=7)
|
|
@ -0,0 +1,304 @@
|
|||
"""Test trophic levels, trophic differences and trophic coherence
|
||||
"""
|
||||
import pytest
|
||||
|
||||
np = pytest.importorskip("numpy")
|
||||
|
||||
import networkx as nx
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
def test_trophic_levels():
|
||||
"""Trivial example
|
||||
"""
|
||||
G = nx.DiGraph()
|
||||
G.add_edge("a", "b")
|
||||
G.add_edge("b", "c")
|
||||
|
||||
d = nx.trophic_levels(G)
|
||||
assert d == {"a": 1, "b": 2, "c": 3}
|
||||
|
||||
|
||||
def test_trophic_levels_levine():
|
||||
"""Example from Figure 5 in Stephen Levine (1980) J. theor. Biol. 83,
|
||||
195-207
|
||||
"""
|
||||
S = nx.DiGraph()
|
||||
S.add_edge(1, 2, weight=1.0)
|
||||
S.add_edge(1, 3, weight=0.2)
|
||||
S.add_edge(1, 4, weight=0.8)
|
||||
S.add_edge(2, 3, weight=0.2)
|
||||
S.add_edge(2, 5, weight=0.3)
|
||||
S.add_edge(4, 3, weight=0.6)
|
||||
S.add_edge(4, 5, weight=0.7)
|
||||
S.add_edge(5, 4, weight=0.2)
|
||||
|
||||
# save copy for later, test intermediate implementation details first
|
||||
S2 = S.copy()
|
||||
|
||||
# drop nodes of in-degree zero
|
||||
z = [nid for nid, d in S.in_degree if d == 0]
|
||||
for nid in z:
|
||||
S.remove_node(nid)
|
||||
|
||||
# find adjacency matrix
|
||||
q = nx.linalg.graphmatrix.adjacency_matrix(S).T
|
||||
|
||||
# fmt: off
|
||||
expected_q = np.array([
|
||||
[0, 0, 0., 0],
|
||||
[0.2, 0, 0.6, 0],
|
||||
[0, 0, 0, 0.2],
|
||||
[0.3, 0, 0.7, 0]
|
||||
])
|
||||
# fmt: on
|
||||
assert np.array_equal(q.todense(), expected_q)
|
||||
|
||||
# must be square, size of number of nodes
|
||||
assert len(q.shape) == 2
|
||||
assert q.shape[0] == q.shape[1]
|
||||
assert q.shape[0] == len(S)
|
||||
|
||||
nn = q.shape[0]
|
||||
|
||||
i = np.eye(nn)
|
||||
n = np.linalg.inv(i - q)
|
||||
y = np.dot(np.asarray(n), np.ones(nn))
|
||||
|
||||
expected_y = np.array([1, 2.07906977, 1.46511628, 2.3255814])
|
||||
assert np.allclose(y, expected_y)
|
||||
|
||||
expected_d = {1: 1, 2: 2, 3: 3.07906977, 4: 2.46511628, 5: 3.3255814}
|
||||
|
||||
d = nx.trophic_levels(S2)
|
||||
|
||||
for nid, level in d.items():
|
||||
expected_level = expected_d[nid]
|
||||
assert almost_equal(expected_level, level)
|
||||
|
||||
|
||||
def test_trophic_levels_simple():
|
||||
matrix_a = np.array([[0, 0], [1, 0]])
|
||||
G = nx.from_numpy_array(matrix_a, create_using=nx.DiGraph)
|
||||
d = nx.trophic_levels(G)
|
||||
assert almost_equal(d[0], 2)
|
||||
assert almost_equal(d[1], 1)
|
||||
|
||||
|
||||
def test_trophic_levels_more_complex():
|
||||
# fmt: off
|
||||
matrix = np.array([
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 0, 0]
|
||||
])
|
||||
# fmt: on
|
||||
G = nx.from_numpy_array(matrix, create_using=nx.DiGraph)
|
||||
d = nx.trophic_levels(G)
|
||||
expected_result = [1, 2, 3, 4]
|
||||
for ind in range(4):
|
||||
assert almost_equal(d[ind], expected_result[ind])
|
||||
|
||||
# fmt: off
|
||||
matrix = np.array([
|
||||
[0, 1, 1, 0],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 0, 0]
|
||||
])
|
||||
# fmt: on
|
||||
G = nx.from_numpy_array(matrix, create_using=nx.DiGraph)
|
||||
d = nx.trophic_levels(G)
|
||||
|
||||
expected_result = [1, 2, 2.5, 3.25]
|
||||
print("Calculated result: ", d)
|
||||
print("Expected Result: ", expected_result)
|
||||
|
||||
for ind in range(4):
|
||||
assert almost_equal(d[ind], expected_result[ind])
|
||||
|
||||
|
||||
def test_trophic_levels_even_more_complex():
|
||||
# fmt: off
|
||||
# Another, bigger matrix
|
||||
matrix = np.array([
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 1, 0],
|
||||
[1, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 0],
|
||||
[0, 0, 0, 1, 0]
|
||||
])
|
||||
# Generated this linear system using pen and paper:
|
||||
K = np.array([
|
||||
[1, 0, -1, 0, 0],
|
||||
[0, 0.5, 0, -0.5, 0],
|
||||
[0, 0, 1, 0, 0],
|
||||
[0, -0.5, 0, 1, -0.5],
|
||||
[0, 0, 0, 0, 1],
|
||||
])
|
||||
# fmt: on
|
||||
result_1 = np.ravel(np.matmul(np.linalg.inv(K), np.ones(5)))
|
||||
G = nx.from_numpy_array(matrix, create_using=nx.DiGraph)
|
||||
result_2 = nx.trophic_levels(G)
|
||||
|
||||
for ind in range(5):
|
||||
assert almost_equal(result_1[ind], result_2[ind])
|
||||
|
||||
|
||||
def test_trophic_levels_singular_matrix():
|
||||
"""Should raise an error with graphs with only non-basal nodes
|
||||
"""
|
||||
matrix = np.identity(4)
|
||||
G = nx.from_numpy_array(matrix, create_using=nx.DiGraph)
|
||||
with pytest.raises(nx.NetworkXError) as e:
|
||||
nx.trophic_levels(G)
|
||||
msg = (
|
||||
"Trophic levels are only defined for graphs where every node "
|
||||
+ "has a path from a basal node (basal nodes are nodes with no "
|
||||
+ "incoming edges)."
|
||||
)
|
||||
assert msg in str(e.value)
|
||||
|
||||
|
||||
def test_trophic_levels_singular_with_basal():
|
||||
"""Should fail to compute if there are any parts of the graph which are not
|
||||
reachable from any basal node (with in-degree zero).
|
||||
"""
|
||||
G = nx.DiGraph()
|
||||
# a has in-degree zero
|
||||
G.add_edge("a", "b")
|
||||
|
||||
# b is one level above a, c and d
|
||||
G.add_edge("c", "b")
|
||||
G.add_edge("d", "b")
|
||||
|
||||
# c and d form a loop, neither are reachable from a
|
||||
G.add_edge("c", "d")
|
||||
G.add_edge("d", "c")
|
||||
|
||||
with pytest.raises(nx.NetworkXError) as e:
|
||||
nx.trophic_levels(G)
|
||||
msg = (
|
||||
"Trophic levels are only defined for graphs where every node "
|
||||
+ "has a path from a basal node (basal nodes are nodes with no "
|
||||
+ "incoming edges)."
|
||||
)
|
||||
assert msg in str(e.value)
|
||||
|
||||
# if self-loops are allowed, smaller example:
|
||||
G = nx.DiGraph()
|
||||
G.add_edge("a", "b") # a has in-degree zero
|
||||
G.add_edge("c", "b") # b is one level above a and c
|
||||
G.add_edge("c", "c") # c has a self-loop
|
||||
with pytest.raises(nx.NetworkXError) as e:
|
||||
nx.trophic_levels(G)
|
||||
msg = (
|
||||
"Trophic levels are only defined for graphs where every node "
|
||||
+ "has a path from a basal node (basal nodes are nodes with no "
|
||||
+ "incoming edges)."
|
||||
)
|
||||
assert msg in str(e.value)
|
||||
|
||||
|
||||
def test_trophic_differences():
|
||||
matrix_a = np.array([[0, 1], [0, 0]])
|
||||
G = nx.from_numpy_array(matrix_a, create_using=nx.DiGraph)
|
||||
diffs = nx.trophic_differences(G)
|
||||
assert almost_equal(diffs[(0, 1)], 1)
|
||||
|
||||
# fmt: off
|
||||
matrix_b = np.array([
|
||||
[0, 1, 1, 0],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 0, 0]
|
||||
])
|
||||
# fmt: on
|
||||
G = nx.from_numpy_array(matrix_b, create_using=nx.DiGraph)
|
||||
diffs = nx.trophic_differences(G)
|
||||
|
||||
assert almost_equal(diffs[(0, 1)], 1)
|
||||
assert almost_equal(diffs[(0, 2)], 1.5)
|
||||
assert almost_equal(diffs[(1, 2)], 0.5)
|
||||
assert almost_equal(diffs[(1, 3)], 1.25)
|
||||
assert almost_equal(diffs[(2, 3)], 0.75)
|
||||
|
||||
|
||||
def test_trophic_incoherence_parameter_no_cannibalism():
|
||||
matrix_a = np.array([[0, 1], [0, 0]])
|
||||
G = nx.from_numpy_array(matrix_a, create_using=nx.DiGraph)
|
||||
q = nx.trophic_incoherence_parameter(G, cannibalism=False)
|
||||
assert almost_equal(q, 0)
|
||||
|
||||
# fmt: off
|
||||
matrix_b = np.array([
|
||||
[0, 1, 1, 0],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 0, 0]
|
||||
])
|
||||
# fmt: on
|
||||
G = nx.from_numpy_array(matrix_b, create_using=nx.DiGraph)
|
||||
q = nx.trophic_incoherence_parameter(G, cannibalism=False)
|
||||
assert almost_equal(q, np.std([1, 1.5, 0.5, 0.75, 1.25]))
|
||||
|
||||
# fmt: off
|
||||
matrix_c = np.array([
|
||||
[0, 1, 1, 0],
|
||||
[0, 1, 1, 1],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 0, 1]
|
||||
])
|
||||
# fmt: on
|
||||
G = nx.from_numpy_array(matrix_c, create_using=nx.DiGraph)
|
||||
q = nx.trophic_incoherence_parameter(G, cannibalism=False)
|
||||
# Ignore the -link
|
||||
assert almost_equal(q, np.std([1, 1.5, 0.5, 0.75, 1.25]))
|
||||
|
||||
# no self-loops case
|
||||
# fmt: off
|
||||
matrix_d = np.array([
|
||||
[0, 1, 1, 0],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 0, 0]
|
||||
])
|
||||
# fmt: on
|
||||
G = nx.from_numpy_array(matrix_d, create_using=nx.DiGraph)
|
||||
q = nx.trophic_incoherence_parameter(G, cannibalism=False)
|
||||
# Ignore the -link
|
||||
assert almost_equal(q, np.std([1, 1.5, 0.5, 0.75, 1.25]))
|
||||
|
||||
|
||||
def test_trophic_incoherence_parameter_cannibalism():
|
||||
matrix_a = np.array([[0, 1], [0, 0]])
|
||||
G = nx.from_numpy_array(matrix_a, create_using=nx.DiGraph)
|
||||
q = nx.trophic_incoherence_parameter(G, cannibalism=True)
|
||||
assert almost_equal(q, 0)
|
||||
|
||||
# fmt: off
|
||||
matrix_b = np.array([
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 1, 0],
|
||||
[1, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 0],
|
||||
[0, 0, 0, 1, 0]
|
||||
])
|
||||
# fmt: on
|
||||
G = nx.from_numpy_array(matrix_b, create_using=nx.DiGraph)
|
||||
q = nx.trophic_incoherence_parameter(G, cannibalism=True)
|
||||
assert almost_equal(q, 2)
|
||||
|
||||
# fmt: off
|
||||
matrix_c = np.array([
|
||||
[0, 1, 1, 0],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 0, 0]
|
||||
])
|
||||
# fmt: on
|
||||
G = nx.from_numpy_array(matrix_c, create_using=nx.DiGraph)
|
||||
q = nx.trophic_incoherence_parameter(G, cannibalism=True)
|
||||
# Ignore the -link
|
||||
assert almost_equal(q, np.std([1, 1.5, 0.5, 0.75, 1.25]))
|
|
@ -0,0 +1,61 @@
|
|||
"""
|
||||
Unit tests for VoteRank.
|
||||
"""
|
||||
|
||||
|
||||
import networkx as nx
|
||||
|
||||
|
||||
class TestVoteRankCentrality:
|
||||
# Example Graph present in reference paper
|
||||
def test_voterank_centrality_1(self):
|
||||
G = nx.Graph()
|
||||
G.add_edges_from(
|
||||
[
|
||||
(7, 8),
|
||||
(7, 5),
|
||||
(7, 9),
|
||||
(5, 0),
|
||||
(0, 1),
|
||||
(0, 2),
|
||||
(0, 3),
|
||||
(0, 4),
|
||||
(1, 6),
|
||||
(2, 6),
|
||||
(3, 6),
|
||||
(4, 6),
|
||||
]
|
||||
)
|
||||
assert [0, 7, 6] == nx.voterank(G)
|
||||
|
||||
# Graph unit test
|
||||
def test_voterank_centrality_2(self):
|
||||
G = nx.florentine_families_graph()
|
||||
d = nx.voterank(G, 4)
|
||||
exact = ["Medici", "Strozzi", "Guadagni", "Castellani"]
|
||||
assert exact == d
|
||||
|
||||
# DiGraph unit test
|
||||
def test_voterank_centrality_3(self):
|
||||
G = nx.gnc_graph(10, seed=7)
|
||||
d = nx.voterank(G, 4)
|
||||
exact = [3, 6, 8]
|
||||
assert exact == d
|
||||
|
||||
# MultiGraph unit test
|
||||
def test_voterank_centrality_4(self):
|
||||
G = nx.MultiGraph()
|
||||
G.add_edges_from(
|
||||
[(0, 1), (0, 1), (1, 2), (2, 5), (2, 5), (5, 6), (5, 6), (2, 4), (4, 3)]
|
||||
)
|
||||
exact = [2, 1, 5, 4]
|
||||
assert exact == nx.voterank(G)
|
||||
|
||||
# MultiDiGraph unit test
|
||||
def test_voterank_centrality_5(self):
|
||||
G = nx.MultiDiGraph()
|
||||
G.add_edges_from(
|
||||
[(0, 1), (0, 1), (1, 2), (2, 5), (2, 5), (5, 6), (5, 6), (2, 4), (4, 3)]
|
||||
)
|
||||
exact = [2, 0, 5, 4]
|
||||
assert exact == nx.voterank(G)
|
Loading…
Add table
Add a link
Reference in a new issue