summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarrod Millman <jarrod.millman@gmail.com>2019-11-19 23:12:09 -0800
committerJarrod Millman <jarrod.millman@gmail.com>2019-11-19 23:36:38 -0800
commita9daddcd6dbd3a9323ed892d8d0c8236deb37e2f (patch)
treeed079a14afbf8c4f1b34510b26cbfee1e3576b6b
parentf34040c8e5c72294c4d9b99dad1ff515a0a06eaf (diff)
downloadnetworkx-a9daddcd6dbd3a9323ed892d8d0c8236deb37e2f.tar.gz
Update style
-rw-r--r--networkx/algorithms/connectivity/tests/test_kcomponents.py204
-rw-r--r--networkx/algorithms/connectivity/tests/test_kcutsets.py41
-rw-r--r--networkx/algorithms/flow/tests/test_gomory_hu.py55
-rw-r--r--networkx/algorithms/flow/tests/test_maxflow_large_graph.py76
-rw-r--r--networkx/algorithms/similarity.py431
-rw-r--r--networkx/tests/test_all_random_functions.py82
-rw-r--r--networkx/tests/test_convert_pandas.py190
7 files changed, 664 insertions, 415 deletions
diff --git a/networkx/algorithms/connectivity/tests/test_kcomponents.py b/networkx/algorithms/connectivity/tests/test_kcomponents.py
index f1160261..fbe111ad 100644
--- a/networkx/algorithms/connectivity/tests/test_kcomponents.py
+++ b/networkx/algorithms/connectivity/tests/test_kcomponents.py
@@ -14,14 +14,12 @@ from networkx.algorithms.connectivity.kcomponents import (
def torrents_and_ferraro_graph():
# Graph from https://arxiv.org/pdf/1503.04476v1 p.26
G = nx.convert_node_labels_to_integers(
- nx.grid_graph([5, 5]),
- label_attribute='labels',
+ nx.grid_graph([5, 5]), label_attribute="labels"
)
- rlabels = nx.get_node_attributes(G, 'labels')
+ rlabels = nx.get_node_attributes(G, "labels")
labels = {v: k for k, v in rlabels.items()}
- for nodes in [(labels[(0, 4)], labels[(1, 4)]),
- (labels[(3, 4)], labels[(4, 4)])]:
+ for nodes in [(labels[(0, 4)], labels[(1, 4)]), (labels[(3, 4)], labels[(4, 4)])]:
new_node = G.order() + 1
# Petersen graph is triconnected
P = nx.petersen_graph()
@@ -46,8 +44,7 @@ def torrents_and_ferraro_graph():
# needed because K5s share only one node.
G.add_edge(new_node + 16, new_node + 8)
- for nodes in [(labels[(0, 0)], labels[(1, 0)]),
- (labels[(3, 0)], labels[(4, 0)])]:
+ for nodes in [(labels[(0, 0)], labels[(1, 0)]), (labels[(3, 0)], labels[(4, 0)])]:
new_node = G.order() + 1
# Petersen graph is triconnected
P = nx.petersen_graph()
@@ -137,10 +134,40 @@ def test_karate():
def test_karate_component_number():
karate_k_num = {
- 0: 4, 1: 4, 2: 4, 3: 4, 4: 3, 5: 3, 6: 3, 7: 4, 8: 4, 9: 2,
- 10: 3, 11: 1, 12: 2, 13: 4, 14: 2, 15: 2, 16: 2, 17: 2,
- 18: 2, 19: 3, 20: 2, 21: 2, 22: 2, 23: 3, 24: 3, 25: 3,
- 26: 2, 27: 3, 28: 3, 29: 3, 30: 4, 31: 3, 32: 4, 33: 4
+ 0: 4,
+ 1: 4,
+ 2: 4,
+ 3: 4,
+ 4: 3,
+ 5: 3,
+ 6: 3,
+ 7: 4,
+ 8: 4,
+ 9: 2,
+ 10: 3,
+ 11: 1,
+ 12: 2,
+ 13: 4,
+ 14: 2,
+ 15: 2,
+ 16: 2,
+ 17: 2,
+ 18: 2,
+ 19: 3,
+ 20: 2,
+ 21: 2,
+ 22: 2,
+ 23: 3,
+ 24: 3,
+ 25: 3,
+ 26: 2,
+ 27: 3,
+ 28: 3,
+ 29: 3,
+ 30: 4,
+ 31: 3,
+ 32: 4,
+ 33: 4,
}
G = nx.karate_club_graph()
k_components = nx.k_components(G)
@@ -156,62 +183,64 @@ def test_davis_southern_women():
def test_davis_southern_women_detail_3_and_4():
solution = {
- 3: [{
- 'Nora Fayette',
- 'E10',
- 'Myra Liddel',
- 'E12',
- 'E14',
- 'Frances Anderson',
- 'Evelyn Jefferson',
- 'Ruth DeSand',
- 'Helen Lloyd',
- 'Eleanor Nye',
- 'E9',
- 'E8',
- 'E5',
- 'E4',
- 'E7',
- 'E6',
- 'E1',
- 'Verne Sanderson',
- 'E3',
- 'E2',
- 'Theresa Anderson',
- 'Pearl Oglethorpe',
- 'Katherina Rogers',
- 'Brenda Rogers',
- 'E13',
- 'Charlotte McDowd',
- 'Sylvia Avondale',
- 'Laura Mandeville',
- },
+ 3: [
+ {
+ "Nora Fayette",
+ "E10",
+ "Myra Liddel",
+ "E12",
+ "E14",
+ "Frances Anderson",
+ "Evelyn Jefferson",
+ "Ruth DeSand",
+ "Helen Lloyd",
+ "Eleanor Nye",
+ "E9",
+ "E8",
+ "E5",
+ "E4",
+ "E7",
+ "E6",
+ "E1",
+ "Verne Sanderson",
+ "E3",
+ "E2",
+ "Theresa Anderson",
+ "Pearl Oglethorpe",
+ "Katherina Rogers",
+ "Brenda Rogers",
+ "E13",
+ "Charlotte McDowd",
+ "Sylvia Avondale",
+ "Laura Mandeville",
+ }
],
- 4: [{
- 'Nora Fayette',
- 'E10',
- 'Verne Sanderson',
- 'E12',
- 'Frances Anderson',
- 'Evelyn Jefferson',
- 'Ruth DeSand',
- 'Helen Lloyd',
- 'Eleanor Nye',
- 'E9',
- 'E8',
- 'E5',
- 'E4',
- 'E7',
- 'E6',
- 'Myra Liddel',
- 'E3',
- 'Theresa Anderson',
- 'Katherina Rogers',
- 'Brenda Rogers',
- 'Charlotte McDowd',
- 'Sylvia Avondale',
- 'Laura Mandeville',
- },
+ 4: [
+ {
+ "Nora Fayette",
+ "E10",
+ "Verne Sanderson",
+ "E12",
+ "Frances Anderson",
+ "Evelyn Jefferson",
+ "Ruth DeSand",
+ "Helen Lloyd",
+ "Eleanor Nye",
+ "E9",
+ "E8",
+ "E5",
+ "E4",
+ "E7",
+ "E6",
+ "Myra Liddel",
+ "E3",
+ "Theresa Anderson",
+ "Katherina Rogers",
+ "Brenda Rogers",
+ "Charlotte McDowd",
+ "Sylvia Avondale",
+ "Laura Mandeville",
+ }
],
}
G = nx.davis_southern_women_graph()
@@ -227,24 +256,37 @@ def test_davis_southern_women_detail_3_and_4():
def test_set_consolidation_rosettacode():
# Tests from http://rosettacode.org/wiki/Set_consolidation
def list_of_sets_equal(result, solution):
- assert (
- {frozenset(s) for s in result} ==
- {frozenset(s) for s in solution})
- question = [{'A', 'B'}, {'C', 'D'}]
- solution = [{'A', 'B'}, {'C', 'D'}]
+ assert {frozenset(s) for s in result} == {frozenset(s) for s in solution}
+
+ question = [{"A", "B"}, {"C", "D"}]
+ solution = [{"A", "B"}, {"C", "D"}]
list_of_sets_equal(_consolidate(question, 1), solution)
- question = [{'A', 'B'}, {'B', 'C'}]
- solution = [{'A', 'B', 'C'}]
+ question = [{"A", "B"}, {"B", "C"}]
+ solution = [{"A", "B", "C"}]
list_of_sets_equal(_consolidate(question, 1), solution)
- question = [{'A', 'B'}, {'C', 'D'}, {'D', 'B'}]
- solution = [{'A', 'C', 'B', 'D'}]
+ question = [{"A", "B"}, {"C", "D"}, {"D", "B"}]
+ solution = [{"A", "C", "B", "D"}]
list_of_sets_equal(_consolidate(question, 1), solution)
- question = [{'H', 'I', 'K'}, {'A', 'B'}, {'C', 'D'}, {'D', 'B'}, {'F', 'G', 'H'}]
- solution = [{'A', 'C', 'B', 'D'}, {'G', 'F', 'I', 'H', 'K'}]
+ question = [{"H", "I", "K"}, {"A", "B"}, {"C", "D"}, {"D", "B"}, {"F", "G", "H"}]
+ solution = [{"A", "C", "B", "D"}, {"G", "F", "I", "H", "K"}]
list_of_sets_equal(_consolidate(question, 1), solution)
- question = [{'A', 'H'}, {'H', 'I', 'K'}, {'A', 'B'}, {'C', 'D'}, {'D', 'B'}, {'F', 'G', 'H'}]
- solution = [{'A', 'C', 'B', 'D', 'G', 'F', 'I', 'H', 'K'}]
+ question = [
+ {"A", "H"},
+ {"H", "I", "K"},
+ {"A", "B"},
+ {"C", "D"},
+ {"D", "B"},
+ {"F", "G", "H"},
+ ]
+ solution = [{"A", "C", "B", "D", "G", "F", "I", "H", "K"}]
list_of_sets_equal(_consolidate(question, 1), solution)
- question = [{'H', 'I', 'K'}, {'A', 'B'}, {'C', 'D'}, {'D', 'B'}, {'F', 'G', 'H'}, {'A', 'H'}]
- solution = [{'A', 'C', 'B', 'D', 'G', 'F', 'I', 'H', 'K'}]
+ question = [
+ {"H", "I", "K"},
+ {"A", "B"},
+ {"C", "D"},
+ {"D", "B"},
+ {"F", "G", "H"},
+ {"A", "H"},
+ ]
+ solution = [{"A", "C", "B", "D", "G", "F", "I", "H", "K"}]
list_of_sets_equal(_consolidate(question, 1), solution)
diff --git a/networkx/algorithms/connectivity/tests/test_kcutsets.py b/networkx/algorithms/connectivity/tests/test_kcutsets.py
index 492b309d..4bb07094 100644
--- a/networkx/algorithms/connectivity/tests/test_kcutsets.py
+++ b/networkx/algorithms/connectivity/tests/test_kcutsets.py
@@ -22,15 +22,18 @@ flow_funcs = [
# Some nice synthetic graphs
##
def graph_example_1():
- G = nx.convert_node_labels_to_integers(nx.grid_graph([5, 5]),
- label_attribute='labels')
- rlabels = nx.get_node_attributes(G, 'labels')
+ G = nx.convert_node_labels_to_integers(
+ nx.grid_graph([5, 5]), label_attribute="labels"
+ )
+ rlabels = nx.get_node_attributes(G, "labels")
labels = {v: k for k, v in rlabels.items()}
- for nodes in [(labels[(0, 0)], labels[(1, 0)]),
- (labels[(0, 4)], labels[(1, 4)]),
- (labels[(3, 0)], labels[(4, 0)]),
- (labels[(3, 4)], labels[(4, 4)])]:
+ for nodes in [
+ (labels[(0, 0)], labels[(1, 0)]),
+ (labels[(0, 4)], labels[(1, 4)]),
+ (labels[(3, 0)], labels[(4, 0)]),
+ (labels[(3, 4)], labels[(4, 4)]),
+ ]:
new_node = G.order() + 1
# Petersen graph is triconnected
P = nx.petersen_graph()
@@ -56,13 +59,13 @@ def graph_example_1():
def torrents_and_ferraro_graph():
- G = nx.convert_node_labels_to_integers(nx.grid_graph([5, 5]),
- label_attribute='labels')
- rlabels = nx.get_node_attributes(G, 'labels')
+ G = nx.convert_node_labels_to_integers(
+ nx.grid_graph([5, 5]), label_attribute="labels"
+ )
+ rlabels = nx.get_node_attributes(G, "labels")
labels = {v: k for k, v in rlabels.items()}
- for nodes in [(labels[(0, 4)], labels[(1, 4)]),
- (labels[(3, 4)], labels[(4, 4)])]:
+ for nodes in [(labels[(0, 4)], labels[(1, 4)]), (labels[(3, 4)], labels[(4, 4)])]:
new_node = G.order() + 1
# Petersen graph is triconnected
P = nx.petersen_graph()
@@ -87,8 +90,7 @@ def torrents_and_ferraro_graph():
# This stupid mistake make one reviewer very angry :P
G.add_edge(new_node + 16, new_node + 8)
- for nodes in [(labels[(0, 0)], labels[(1, 0)]),
- (labels[(3, 0)], labels[(4, 0)])]:
+ for nodes in [(labels[(0, 0)], labels[(1, 0)]), (labels[(3, 0)], labels[(4, 0)])]:
new_node = G.order() + 1
# Petersen graph is triconnected
P = nx.petersen_graph()
@@ -209,8 +211,7 @@ def test_disconnected_graph():
def test_alternative_flow_functions():
- graphs = [nx.grid_2d_graph(4, 4),
- nx.cycle_graph(5)]
+ graphs = [nx.grid_2d_graph(4, 4), nx.cycle_graph(5)]
for G in graphs:
node_conn = nx.node_connectivity(G)
for flow_func in flow_funcs:
@@ -261,13 +262,7 @@ def test_cycle_graph():
def test_complete_graph():
G = nx.complete_graph(5)
- solution = [
- {0, 1, 2, 3},
- {0, 1, 2, 4},
- {0, 1, 3, 4},
- {0, 2, 3, 4},
- {1, 2, 3, 4},
- ]
+ solution = [{0, 1, 2, 3}, {0, 1, 2, 4}, {0, 1, 3, 4}, {0, 2, 3, 4}, {1, 2, 3, 4}]
cuts = list(nx.all_node_cuts(G))
assert len(solution) == len(cuts)
for cut in cuts:
diff --git a/networkx/algorithms/flow/tests/test_gomory_hu.py b/networkx/algorithms/flow/tests/test_gomory_hu.py
index b82a32f7..0d9ded84 100644
--- a/networkx/algorithms/flow/tests/test_gomory_hu.py
+++ b/networkx/algorithms/flow/tests/test_gomory_hu.py
@@ -18,10 +18,9 @@ flow_funcs = [
class TestGomoryHuTree:
-
def minimum_edge_weight(self, T, u, v):
- path = nx.shortest_path(T, u, v, weight='weight')
- return min((T[u][v]['weight'], (u, v)) for (u, v) in zip(path, path[1:]))
+ path = nx.shortest_path(T, u, v, weight="weight")
+ return min((T[u][v]["weight"], (u, v)) for (u, v) in zip(path, path[1:]))
def compute_cutset(self, G, T_orig, edge):
T = T_orig.copy()
@@ -34,61 +33,56 @@ class TestGomoryHuTree:
def test_default_flow_function_karate_club_graph(self):
G = nx.karate_club_graph()
- nx.set_edge_attributes(G, 1, 'capacity')
+ nx.set_edge_attributes(G, 1, "capacity")
T = nx.gomory_hu_tree(G)
assert nx.is_tree(T)
for u, v in combinations(G, 2):
cut_value, edge = self.minimum_edge_weight(T, u, v)
- assert (nx.minimum_cut_value(G, u, v) ==
- cut_value)
+ assert nx.minimum_cut_value(G, u, v) == cut_value
def test_karate_club_graph(self):
G = nx.karate_club_graph()
- nx.set_edge_attributes(G, 1, 'capacity')
+ nx.set_edge_attributes(G, 1, "capacity")
for flow_func in flow_funcs:
T = nx.gomory_hu_tree(G, flow_func=flow_func)
assert nx.is_tree(T)
for u, v in combinations(G, 2):
cut_value, edge = self.minimum_edge_weight(T, u, v)
- assert (nx.minimum_cut_value(G, u, v) ==
- cut_value)
+ assert nx.minimum_cut_value(G, u, v) == cut_value
def test_davis_southern_women_graph(self):
G = nx.davis_southern_women_graph()
- nx.set_edge_attributes(G, 1, 'capacity')
+ nx.set_edge_attributes(G, 1, "capacity")
for flow_func in flow_funcs:
T = nx.gomory_hu_tree(G, flow_func=flow_func)
assert nx.is_tree(T)
for u, v in combinations(G, 2):
cut_value, edge = self.minimum_edge_weight(T, u, v)
- assert (nx.minimum_cut_value(G, u, v) ==
- cut_value)
+ assert nx.minimum_cut_value(G, u, v) == cut_value
def test_florentine_families_graph(self):
G = nx.florentine_families_graph()
- nx.set_edge_attributes(G, 1, 'capacity')
+ nx.set_edge_attributes(G, 1, "capacity")
for flow_func in flow_funcs:
T = nx.gomory_hu_tree(G, flow_func=flow_func)
assert nx.is_tree(T)
for u, v in combinations(G, 2):
cut_value, edge = self.minimum_edge_weight(T, u, v)
- assert (nx.minimum_cut_value(G, u, v) ==
- cut_value)
+ assert nx.minimum_cut_value(G, u, v) == cut_value
def test_les_miserables_graph_cutset(self):
G = nx.les_miserables_graph()
- nx.set_edge_attributes(G, 1, 'capacity')
+ nx.set_edge_attributes(G, 1, "capacity")
for flow_func in flow_funcs:
T = nx.gomory_hu_tree(G, flow_func=flow_func)
assert nx.is_tree(T)
for u, v in combinations(G, 2):
cut_value, edge = self.minimum_edge_weight(T, u, v)
- assert (nx.minimum_cut_value(G, u, v) ==
- cut_value)
+ assert nx.minimum_cut_value(G, u, v) == cut_value
def test_karate_club_graph_cutset(self):
G = nx.karate_club_graph()
- nx.set_edge_attributes(G, 1, 'capacity')
+ nx.set_edge_attributes(G, 1, "capacity")
T = nx.gomory_hu_tree(G)
assert nx.is_tree(T)
u, v = 0, 33
@@ -99,18 +93,25 @@ class TestGomoryHuTree:
def test_wikipedia_example(self):
# Example from https://en.wikipedia.org/wiki/Gomory%E2%80%93Hu_tree
G = nx.Graph()
- G.add_weighted_edges_from((
- (0, 1, 1), (0, 2, 7), (1, 2, 1),
- (1, 3, 3), (1, 4, 2), (2, 4, 4),
- (3, 4, 1), (3, 5, 6), (4, 5, 2),
- ))
+ G.add_weighted_edges_from(
+ (
+ (0, 1, 1),
+ (0, 2, 7),
+ (1, 2, 1),
+ (1, 3, 3),
+ (1, 4, 2),
+ (2, 4, 4),
+ (3, 4, 1),
+ (3, 5, 6),
+ (4, 5, 2),
+ )
+ )
for flow_func in flow_funcs:
- T = nx.gomory_hu_tree(G, capacity='weight', flow_func=flow_func)
+ T = nx.gomory_hu_tree(G, capacity="weight", flow_func=flow_func)
assert nx.is_tree(T)
for u, v in combinations(G, 2):
cut_value, edge = self.minimum_edge_weight(T, u, v)
- assert (nx.minimum_cut_value(G, u, v, capacity='weight') ==
- cut_value)
+ assert nx.minimum_cut_value(G, u, v, capacity="weight") == cut_value
def test_directed_raises(self):
with pytest.raises(nx.NetworkXNotImplemented):
diff --git a/networkx/algorithms/flow/tests/test_maxflow_large_graph.py b/networkx/algorithms/flow/tests/test_maxflow_large_graph.py
index e152cb50..dceba17b 100644
--- a/networkx/algorithms/flow/tests/test_maxflow_large_graph.py
+++ b/networkx/algorithms/flow/tests/test_maxflow_large_graph.py
@@ -30,29 +30,27 @@ def gen_pyramid(N):
G = nx.DiGraph()
for i in range(N - 1):
- cap = 1. / (i + 2)
+ cap = 1.0 / (i + 2)
for j in range(i + 1):
- G.add_edge((i, j), (i + 1, j),
- capacity=cap)
- cap = 1. / (i + 1) - cap
- G.add_edge((i, j), (i + 1, j + 1),
- capacity=cap)
- cap = 1. / (i + 2) - cap
+ G.add_edge((i, j), (i + 1, j), capacity=cap)
+ cap = 1.0 / (i + 1) - cap
+ G.add_edge((i, j), (i + 1, j + 1), capacity=cap)
+ cap = 1.0 / (i + 2) - cap
for j in range(N):
- G.add_edge((N - 1, j), 't')
+ G.add_edge((N - 1, j), "t")
return G
def read_graph(name):
dirname = os.path.dirname(__file__)
- path = os.path.join(dirname, name + '.gpickle.bz2')
+ path = os.path.join(dirname, name + ".gpickle.bz2")
return nx.read_gpickle(path)
def validate_flows(G, s, t, soln_value, R, flow_func):
- flow_value = R.graph['flow_value']
+ flow_value = R.graph["flow_value"]
flow_dict = build_flow_dict(G, R)
assert soln_value == flow_value, msg.format(flow_func.__name__)
assert set(G) == set(flow_dict), msg.format(flow_func.__name__)
@@ -61,7 +59,9 @@ def validate_flows(G, s, t, soln_value, R, flow_func):
excess = {u: 0 for u in flow_dict}
for u in flow_dict:
for v, flow in flow_dict[u].items():
- assert flow <= G[u][v].get('capacity', float('inf')), msg.format(flow_func.__name__)
+ assert flow <= G[u][v].get("capacity", float("inf")), msg.format(
+ flow_func.__name__
+ )
assert flow >= 0, msg.format(flow_func.__name__)
excess[u] -= flow
excess[v] += flow
@@ -75,16 +75,15 @@ def validate_flows(G, s, t, soln_value, R, flow_func):
class TestMaxflowLargeGraph:
-
def test_complete_graph(self):
N = 50
G = nx.complete_graph(N)
- nx.set_edge_attributes(G, 5, 'capacity')
- R = build_residual_network(G, 'capacity')
+ nx.set_edge_attributes(G, 5, "capacity")
+ R = build_residual_network(G, "capacity")
kwargs = dict(residual=R)
for flow_func in flow_funcs:
- kwargs['flow_func'] = flow_func
+ kwargs["flow_func"] = flow_func
flow_value = nx.maximum_flow_value(G, 1, 2, **kwargs)
assert flow_value == 5 * (N - 1), msg.format(flow_func.__name__)
@@ -92,56 +91,55 @@ class TestMaxflowLargeGraph:
N = 10
# N = 100 # this gives a graph with 5051 nodes
G = gen_pyramid(N)
- R = build_residual_network(G, 'capacity')
+ R = build_residual_network(G, "capacity")
kwargs = dict(residual=R)
for flow_func in flow_funcs:
- kwargs['flow_func'] = flow_func
- flow_value = nx.maximum_flow_value(G, (0, 0), 't', **kwargs)
- assert almost_equal(flow_value, 1.), msg.format(flow_func.__name__)
+ kwargs["flow_func"] = flow_func
+ flow_value = nx.maximum_flow_value(G, (0, 0), "t", **kwargs)
+ assert almost_equal(flow_value, 1.0), msg.format(flow_func.__name__)
def test_gl1(self):
- G = read_graph('gl1')
+ G = read_graph("gl1")
s = 1
t = len(G)
- R = build_residual_network(G, 'capacity')
+ R = build_residual_network(G, "capacity")
kwargs = dict(residual=R)
# do one flow_func to save time
flow_func = flow_funcs[0]
- validate_flows(G, s, t, 156545, flow_func(G, s, t, **kwargs),
- flow_func)
-# for flow_func in flow_funcs:
-# validate_flows(G, s, t, 156545, flow_func(G, s, t, **kwargs),
-# flow_func)
+ validate_flows(G, s, t, 156545, flow_func(G, s, t, **kwargs), flow_func)
+
+ # for flow_func in flow_funcs:
+ # validate_flows(G, s, t, 156545, flow_func(G, s, t, **kwargs),
+ # flow_func)
def test_gw1(self):
- G = read_graph('gw1')
+ G = read_graph("gw1")
s = 1
t = len(G)
- R = build_residual_network(G, 'capacity')
+ R = build_residual_network(G, "capacity")
kwargs = dict(residual=R)
for flow_func in flow_funcs:
- validate_flows(G, s, t, 1202018, flow_func(G, s, t, **kwargs),
- flow_func)
+ validate_flows(G, s, t, 1202018, flow_func(G, s, t, **kwargs), flow_func)
def test_wlm3(self):
- G = read_graph('wlm3')
+ G = read_graph("wlm3")
s = 1
t = len(G)
- R = build_residual_network(G, 'capacity')
+ R = build_residual_network(G, "capacity")
kwargs = dict(residual=R)
# do one flow_func to save time
flow_func = flow_funcs[0]
- validate_flows(G, s, t, 11875108, flow_func(G, s, t, **kwargs),
- flow_func)
-# for flow_func in flow_funcs:
-# validate_flows(G, s, t, 11875108, flow_func(G, s, t, **kwargs),
-# flow_func)
+ validate_flows(G, s, t, 11875108, flow_func(G, s, t, **kwargs), flow_func)
+
+ # for flow_func in flow_funcs:
+ # validate_flows(G, s, t, 11875108, flow_func(G, s, t, **kwargs),
+ # flow_func)
def test_preflow_push_global_relabel(self):
- G = read_graph('gw1')
+ G = read_graph("gw1")
R = preflow_push(G, 1, len(G), global_relabel_freq=50)
- assert R.graph['flow_value'] == 1202018
+ assert R.graph["flow_value"] == 1202018
diff --git a/networkx/algorithms/similarity.py b/networkx/algorithms/similarity.py
index 985e9500..dfd95efc 100644
--- a/networkx/algorithms/similarity.py
+++ b/networkx/algorithms/similarity.py
@@ -16,12 +16,12 @@ from itertools import product
import networkx as nx
__all__ = [
- 'graph_edit_distance',
- 'optimal_edit_paths',
- 'optimize_graph_edit_distance',
- 'optimize_edit_paths',
- 'simrank_similarity',
- 'simrank_similarity_numpy',
+ "graph_edit_distance",
+ "optimal_edit_paths",
+ "optimize_graph_edit_distance",
+ "optimize_edit_paths",
+ "simrank_similarity",
+ "simrank_similarity_numpy",
]
@@ -29,12 +29,19 @@ def debug_print(*args, **kwargs):
print(*args, **kwargs)
-def graph_edit_distance(G1, G2, node_match=None, edge_match=None,
- node_subst_cost=None, node_del_cost=None,
- node_ins_cost=None,
- edge_subst_cost=None, edge_del_cost=None,
- edge_ins_cost=None,
- upper_bound=None):
+def graph_edit_distance(
+ G1,
+ G2,
+ node_match=None,
+ edge_match=None,
+ node_subst_cost=None,
+ node_del_cost=None,
+ node_ins_cost=None,
+ edge_subst_cost=None,
+ edge_del_cost=None,
+ edge_ins_cost=None,
+ upper_bound=None,
+):
"""Returns GED (graph edit distance) between graphs G1 and G2.
Graph edit distance is a graph similarity measure analogous to
@@ -153,22 +160,38 @@ def graph_edit_distance(G1, G2, node_match=None, edge_match=None,
"""
bestcost = None
- for vertex_path, edge_path, cost in \
- optimize_edit_paths(G1, G2, node_match, edge_match,
- node_subst_cost, node_del_cost, node_ins_cost,
- edge_subst_cost, edge_del_cost, edge_ins_cost,
- upper_bound, True):
+ for vertex_path, edge_path, cost in optimize_edit_paths(
+ G1,
+ G2,
+ node_match,
+ edge_match,
+ node_subst_cost,
+ node_del_cost,
+ node_ins_cost,
+ edge_subst_cost,
+ edge_del_cost,
+ edge_ins_cost,
+ upper_bound,
+ True,
+ ):
# assert bestcost is None or cost < bestcost
bestcost = cost
return bestcost
-def optimal_edit_paths(G1, G2, node_match=None, edge_match=None,
- node_subst_cost=None, node_del_cost=None,
- node_ins_cost=None,
- edge_subst_cost=None, edge_del_cost=None,
- edge_ins_cost=None,
- upper_bound=None):
+def optimal_edit_paths(
+ G1,
+ G2,
+ node_match=None,
+ edge_match=None,
+ node_subst_cost=None,
+ node_del_cost=None,
+ node_ins_cost=None,
+ edge_subst_cost=None,
+ edge_del_cost=None,
+ edge_ins_cost=None,
+ upper_bound=None,
+):
"""Returns all minimum-cost edit paths transforming G1 to G2.
Graph edit path is a sequence of node and edge edit operations
@@ -296,11 +319,20 @@ def optimal_edit_paths(G1, G2, node_match=None, edge_match=None,
"""
paths = list()
bestcost = None
- for vertex_path, edge_path, cost in \
- optimize_edit_paths(G1, G2, node_match, edge_match,
- node_subst_cost, node_del_cost, node_ins_cost,
- edge_subst_cost, edge_del_cost, edge_ins_cost,
- upper_bound, False):
+ for vertex_path, edge_path, cost in optimize_edit_paths(
+ G1,
+ G2,
+ node_match,
+ edge_match,
+ node_subst_cost,
+ node_del_cost,
+ node_ins_cost,
+ edge_subst_cost,
+ edge_del_cost,
+ edge_ins_cost,
+ upper_bound,
+ False,
+ ):
# assert bestcost is None or cost <= bestcost
if bestcost is not None and cost < bestcost:
paths = list()
@@ -309,12 +341,19 @@ def optimal_edit_paths(G1, G2, node_match=None, edge_match=None,
return paths, bestcost
-def optimize_graph_edit_distance(G1, G2, node_match=None, edge_match=None,
- node_subst_cost=None, node_del_cost=None,
- node_ins_cost=None,
- edge_subst_cost=None, edge_del_cost=None,
- edge_ins_cost=None,
- upper_bound=None):
+def optimize_graph_edit_distance(
+ G1,
+ G2,
+ node_match=None,
+ edge_match=None,
+ node_subst_cost=None,
+ node_del_cost=None,
+ node_ins_cost=None,
+ edge_subst_cost=None,
+ edge_del_cost=None,
+ edge_ins_cost=None,
+ upper_bound=None,
+):
"""Returns consecutive approximations of GED (graph edit distance)
between graphs G1 and G2.
@@ -435,20 +474,37 @@ def optimize_graph_edit_distance(G1, G2, node_match=None, edge_match=None,
<10.5220/0005209202710278>. <hal-01168816>
https://hal.archives-ouvertes.fr/hal-01168816
"""
- for vertex_path, edge_path, cost in \
- optimize_edit_paths(G1, G2, node_match, edge_match,
- node_subst_cost, node_del_cost, node_ins_cost,
- edge_subst_cost, edge_del_cost, edge_ins_cost,
- upper_bound, True):
+ for vertex_path, edge_path, cost in optimize_edit_paths(
+ G1,
+ G2,
+ node_match,
+ edge_match,
+ node_subst_cost,
+ node_del_cost,
+ node_ins_cost,
+ edge_subst_cost,
+ edge_del_cost,
+ edge_ins_cost,
+ upper_bound,
+ True,
+ ):
yield cost
-def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
- node_subst_cost=None, node_del_cost=None,
- node_ins_cost=None,
- edge_subst_cost=None, edge_del_cost=None,
- edge_ins_cost=None,
- upper_bound=None, strictly_decreasing=True):
+def optimize_edit_paths(
+ G1,
+ G2,
+ node_match=None,
+ edge_match=None,
+ node_subst_cost=None,
+ node_del_cost=None,
+ node_ins_cost=None,
+ edge_subst_cost=None,
+ edge_del_cost=None,
+ edge_ins_cost=None,
+ upper_bound=None,
+ strictly_decreasing=True,
+):
"""GED (graph edit distance) calculation: advanced interface.
Graph edit path is a sequence of node and edge edit operations
@@ -603,8 +659,9 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
lsa_row_ind[dummy_ind] = lsa_col_ind[subst_ind] + m
lsa_col_ind[dummy_ind] = lsa_row_ind[subst_ind] + n
- return CostMatrix(C, lsa_row_ind, lsa_col_ind,
- C[lsa_row_ind, lsa_col_ind].sum())
+ return CostMatrix(
+ C, lsa_row_ind, lsa_col_ind, C[lsa_row_ind, lsa_col_ind].sum()
+ )
def extract_C(C, i, j, m, n):
# assert(C.shape == (m + n, m + n))
@@ -646,12 +703,18 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
N = len(pending_h)
# assert Ce.C.shape == (M + N, M + N)
- g_ind = [i for i in range(M) if pending_g[i][:2] == (u, u) or
- any(pending_g[i][:2] in ((p, u), (u, p))
- for p, q in matched_uv)]
- h_ind = [j for j in range(N) if pending_h[j][:2] == (v, v) or
- any(pending_h[j][:2] in ((q, v), (v, q))
- for p, q in matched_uv)]
+ g_ind = [
+ i
+ for i in range(M)
+ if pending_g[i][:2] == (u, u)
+ or any(pending_g[i][:2] in ((p, u), (u, p)) for p, q in matched_uv)
+ ]
+ h_ind = [
+ j
+ for j in range(N)
+ if pending_h[j][:2] == (v, v)
+ or any(pending_h[j][:2] in ((q, v), (v, q)) for p, q in matched_uv)
+ ]
m = len(g_ind)
n = len(h_ind)
@@ -666,13 +729,16 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
for l, j in zip(range(n), h_ind):
h = pending_h[j][:2]
if nx.is_directed(G1) or nx.is_directed(G2):
- if any(g == (p, u) and h == (q, v) or
- g == (u, p) and h == (v, q)
- for p, q in matched_uv):
+ if any(
+ g == (p, u) and h == (q, v) or g == (u, p) and h == (v, q)
+ for p, q in matched_uv
+ ):
continue
else:
- if any(g in ((p, u), (u, p)) and h in ((q, v), (v, q))
- for p, q in matched_uv):
+ if any(
+ g in ((p, u), (u, p)) and h in ((q, v), (v, q))
+ for p, q in matched_uv
+ ):
continue
if g == (u, u):
continue
@@ -681,10 +747,14 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
C[k, l] = inf
localCe = make_CostMatrix(C, m, n)
- ij = list((g_ind[k] if k < m else M + h_ind[l],
- h_ind[l] if l < n else N + g_ind[k])
- for k, l in zip(localCe.lsa_row_ind, localCe.lsa_col_ind)
- if k < m or l < n)
+ ij = list(
+ (
+ g_ind[k] if k < m else M + h_ind[l],
+ h_ind[l] if l < n else N + g_ind[k],
+ )
+ for k, l in zip(localCe.lsa_row_ind, localCe.lsa_col_ind)
+ if k < m or l < n
+ )
else:
ij = []
@@ -701,8 +771,9 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
else:
return Ce
- def get_edit_ops(matched_uv, pending_u, pending_v, Cv,
- pending_g, pending_h, Ce, matched_cost):
+ def get_edit_ops(
+ matched_uv, pending_u, pending_v, Cv, pending_g, pending_h, Ce, matched_cost
+ ):
"""
Parameters:
matched_uv: partial vertex edit path
@@ -730,57 +801,86 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
# assert Cv.C.shape == (m + n, m + n)
# 1) a vertex mapping from optimal linear sum assignment
- i, j = min((k, l) for k, l in zip(Cv.lsa_row_ind, Cv.lsa_col_ind)
- if k < m or l < n)
- xy, localCe = match_edges(pending_u[i] if i < m else None,
- pending_v[j] if j < n else None,
- pending_g, pending_h, Ce, matched_uv)
+ i, j = min(
+ (k, l) for k, l in zip(Cv.lsa_row_ind, Cv.lsa_col_ind) if k < m or l < n
+ )
+ xy, localCe = match_edges(
+ pending_u[i] if i < m else None,
+ pending_v[j] if j < n else None,
+ pending_g,
+ pending_h,
+ Ce,
+ matched_uv,
+ )
Ce_xy = reduce_Ce(Ce, xy, len(pending_g), len(pending_h))
# assert Ce.ls <= localCe.ls + Ce_xy.ls
if prune(matched_cost + Cv.ls + localCe.ls + Ce_xy.ls):
pass
else:
# get reduced Cv efficiently
- Cv_ij = CostMatrix(reduce_C(Cv.C, (i,), (j,), m, n),
- reduce_ind(Cv.lsa_row_ind, (i, m + j)),
- reduce_ind(Cv.lsa_col_ind, (j, n + i)),
- Cv.ls - Cv.C[i, j])
+ Cv_ij = CostMatrix(
+ reduce_C(Cv.C, (i,), (j,), m, n),
+ reduce_ind(Cv.lsa_row_ind, (i, m + j)),
+ reduce_ind(Cv.lsa_col_ind, (j, n + i)),
+ Cv.ls - Cv.C[i, j],
+ )
yield (i, j), Cv_ij, xy, Ce_xy, Cv.C[i, j] + localCe.ls
# 2) other candidates, sorted by lower-bound cost estimate
other = list()
fixed_i, fixed_j = i, j
if m <= n:
- candidates = ((t, fixed_j) for t in range(m + n)
- if t != fixed_i and (t < m or t == m + fixed_j))
+ candidates = (
+ (t, fixed_j)
+ for t in range(m + n)
+ if t != fixed_i and (t < m or t == m + fixed_j)
+ )
else:
- candidates = ((fixed_i, t) for t in range(m + n)
- if t != fixed_j and (t < n or t == n + fixed_i))
+ candidates = (
+ (fixed_i, t)
+ for t in range(m + n)
+ if t != fixed_j and (t < n or t == n + fixed_i)
+ )
for i, j in candidates:
if prune(matched_cost + Cv.C[i, j] + Ce.ls):
continue
- Cv_ij = make_CostMatrix(reduce_C(Cv.C, (i,), (j,), m, n),
- m - 1 if i < m else m,
- n - 1 if j < n else n)
+ Cv_ij = make_CostMatrix(
+ reduce_C(Cv.C, (i,), (j,), m, n),
+ m - 1 if i < m else m,
+ n - 1 if j < n else n,
+ )
# assert Cv.ls <= Cv.C[i, j] + Cv_ij.ls
if prune(matched_cost + Cv.C[i, j] + Cv_ij.ls + Ce.ls):
continue
- xy, localCe = match_edges(pending_u[i] if i < m else None,
- pending_v[j] if j < n else None,
- pending_g, pending_h, Ce, matched_uv)
+ xy, localCe = match_edges(
+ pending_u[i] if i < m else None,
+ pending_v[j] if j < n else None,
+ pending_g,
+ pending_h,
+ Ce,
+ matched_uv,
+ )
if prune(matched_cost + Cv.C[i, j] + Cv_ij.ls + localCe.ls):
continue
Ce_xy = reduce_Ce(Ce, xy, len(pending_g), len(pending_h))
# assert Ce.ls <= localCe.ls + Ce_xy.ls
- if prune(matched_cost + Cv.C[i, j] + Cv_ij.ls + localCe.ls +
- Ce_xy.ls):
+ if prune(matched_cost + Cv.C[i, j] + Cv_ij.ls + localCe.ls + Ce_xy.ls):
continue
other.append(((i, j), Cv_ij, xy, Ce_xy, Cv.C[i, j] + localCe.ls))
yield from sorted(other, key=lambda t: t[4] + t[1].ls + t[3].ls)
- def get_edit_paths(matched_uv, pending_u, pending_v, Cv,
- matched_gh, pending_g, pending_h, Ce, matched_cost):
+ def get_edit_paths(
+ matched_uv,
+ pending_u,
+ pending_v,
+ Cv,
+ matched_gh,
+ pending_g,
+ pending_h,
+ Ce,
+ matched_cost,
+ ):
"""
Parameters:
matched_uv: partial vertex edit path
@@ -833,8 +933,16 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
yield matched_uv, matched_gh, matched_cost
else:
- edit_ops = get_edit_ops(matched_uv, pending_u, pending_v, Cv,
- pending_g, pending_h, Ce, matched_cost)
+ edit_ops = get_edit_ops(
+ matched_uv,
+ pending_u,
+ pending_v,
+ Cv,
+ pending_g,
+ pending_h,
+ Ce,
+ matched_cost,
+ )
for ij, Cv_ij, xy, Ce_xy, edit_cost in edit_ops:
i, j = ij
# assert Cv.C[i, j] + sum(Ce.C[t] for t in xy) == edit_cost
@@ -848,20 +956,34 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
for x, y in xy:
len_g = len(pending_g)
len_h = len(pending_h)
- matched_gh.append((pending_g[x] if x < len_g else None,
- pending_h[y] if y < len_h else None))
+ matched_gh.append(
+ (
+ pending_g[x] if x < len_g else None,
+ pending_h[y] if y < len_h else None,
+ )
+ )
sortedx = list(sorted(x for x, y in xy))
sortedy = list(sorted(y for x, y in xy))
- G = list((pending_g.pop(x) if x < len(pending_g) else None)
- for x in reversed(sortedx))
- H = list((pending_h.pop(y) if y < len(pending_h) else None)
- for y in reversed(sortedy))
-
- yield from get_edit_paths(matched_uv, pending_u, pending_v,
- Cv_ij,
- matched_gh, pending_g, pending_h,
- Ce_xy,
- matched_cost + edit_cost)
+ G = list(
+ (pending_g.pop(x) if x < len(pending_g) else None)
+ for x in reversed(sortedx)
+ )
+ H = list(
+ (pending_h.pop(y) if y < len(pending_h) else None)
+ for y in reversed(sortedy)
+ )
+
+ yield from get_edit_paths(
+ matched_uv,
+ pending_u,
+ pending_v,
+ Cv_ij,
+ matched_gh,
+ pending_g,
+ pending_h,
+ Ce_xy,
+ matched_cost + edit_cost,
+ )
# backtrack
if u is not None:
@@ -888,13 +1010,21 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
n = len(pending_v)
C = np.zeros((m + n, m + n))
if node_subst_cost:
- C[0:m, 0:n] = np.array([node_subst_cost(G1.nodes[u], G2.nodes[v])
- for u in pending_u for v in pending_v]
- ).reshape(m, n)
+ C[0:m, 0:n] = np.array(
+ [
+ node_subst_cost(G1.nodes[u], G2.nodes[v])
+ for u in pending_u
+ for v in pending_v
+ ]
+ ).reshape(m, n)
elif node_match:
- C[0:m, 0:n] = np.array([1 - int(node_match(G1.nodes[u], G2.nodes[v]))
- for u in pending_u for v in pending_v]
- ).reshape(m, n)
+ C[0:m, 0:n] = np.array(
+ [
+ 1 - int(node_match(G1.nodes[u], G2.nodes[v]))
+ for u in pending_u
+ for v in pending_v
+ ]
+ ).reshape(m, n)
else:
# all zeroes
pass
@@ -910,12 +1040,12 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
ins_costs = [1] * len(pending_v)
# assert not n or min(ins_costs) >= 0
inf = C[0:m, 0:n].sum() + sum(del_costs) + sum(ins_costs) + 1
- C[0:m, n:n + m] = np.array([del_costs[i] if i == j else inf
- for i in range(m) for j in range(m)]
- ).reshape(m, m)
- C[m:m + n, 0:n] = np.array([ins_costs[i] if i == j else inf
- for i in range(n) for j in range(n)]
- ).reshape(n, n)
+ C[0:m, n : n + m] = np.array(
+ [del_costs[i] if i == j else inf for i in range(m) for j in range(m)]
+ ).reshape(m, m)
+ C[m : m + n, 0:n] = np.array(
+ [ins_costs[i] if i == j else inf for i in range(n) for j in range(n)]
+ ).reshape(n, n)
Cv = make_CostMatrix(C, m, n)
# debug_print('Cv: {} x {}'.format(m, n))
# debug_print(Cv.C)
@@ -928,13 +1058,21 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
n = len(pending_h)
C = np.zeros((m + n, m + n))
if edge_subst_cost:
- C[0:m, 0:n] = np.array([edge_subst_cost(G1.edges[g], G2.edges[h])
- for g in pending_g for h in pending_h]
- ).reshape(m, n)
+ C[0:m, 0:n] = np.array(
+ [
+ edge_subst_cost(G1.edges[g], G2.edges[h])
+ for g in pending_g
+ for h in pending_h
+ ]
+ ).reshape(m, n)
elif edge_match:
- C[0:m, 0:n] = np.array([1 - int(edge_match(G1.edges[g], G2.edges[h]))
- for g in pending_g for h in pending_h]
- ).reshape(m, n)
+ C[0:m, 0:n] = np.array(
+ [
+ 1 - int(edge_match(G1.edges[g], G2.edges[h]))
+ for g in pending_g
+ for h in pending_h
+ ]
+ ).reshape(m, n)
else:
# all zeroes
pass
@@ -950,12 +1088,12 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
ins_costs = [1] * len(pending_h)
# assert not n or min(ins_costs) >= 0
inf = C[0:m, 0:n].sum() + sum(del_costs) + sum(ins_costs) + 1
- C[0:m, n:n + m] = np.array([del_costs[i] if i == j else inf
- for i in range(m) for j in range(m)]
- ).reshape(m, m)
- C[m:m + n, 0:n] = np.array([ins_costs[i] if i == j else inf
- for i in range(n) for j in range(n)]
- ).reshape(n, n)
+ C[0:m, n : n + m] = np.array(
+ [del_costs[i] if i == j else inf for i in range(m) for j in range(m)]
+ ).reshape(m, m)
+ C[m : m + n, 0:n] = np.array(
+ [ins_costs[i] if i == j else inf for i in range(n) for j in range(n)]
+ ).reshape(n, n)
Ce = make_CostMatrix(C, m, n)
# debug_print('Ce: {} x {}'.format(m, n))
# debug_print(Ce.C)
@@ -966,6 +1104,7 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
# initial upper-bound estimate
# NOTE: should work for empty graph
self.value = Cv.C.sum() + Ce.C.sum() + 1
+
maxcost = MaxCost()
def prune(cost):
@@ -979,9 +1118,9 @@ def optimize_edit_paths(G1, G2, node_match=None, edge_match=None,
# Now go!
- for vertex_path, edge_path, cost in \
- get_edit_paths([], pending_u, pending_v, Cv,
- [], pending_g, pending_h, Ce, 0):
+ for vertex_path, edge_path, cost in get_edit_paths(
+ [], pending_u, pending_v, Cv, [], pending_g, pending_h, Ce, 0
+ ):
# assert sorted(G1.nodes) == sorted(u for u, v in vertex_path if u is not None)
# assert sorted(G2.nodes) == sorted(v for u, v in vertex_path if v is not None)
# assert sorted(G1.edges) == sorted(g for g, h in edge_path if g is not None)
@@ -1026,8 +1165,14 @@ def _is_close(d1, d2, atolerance=0, rtolerance=0):
return all(all(_is_close(d1[u][v], d2[u][v]) for v in d1[u]) for u in d1)
-def simrank_similarity(G, source=None, target=None, importance_factor=0.9,
- max_iterations=100, tolerance=1e-4):
+def simrank_similarity(
+ G,
+ source=None,
+ target=None,
+ importance_factor=0.9,
+ max_iterations=100,
+ tolerance=1e-4,
+):
"""Returns the SimRank similarity of nodes in the graph ``G``.
SimRank is a similarity metric that says "two objects are considered
@@ -1121,15 +1266,19 @@ def simrank_similarity(G, source=None, target=None, importance_factor=0.9,
# These functions compute the update to the similarity value of the nodes
# `u` and `v` with respect to the previous similarity values.
- def avg_sim(s): return sum(newsim[w][x] for (w, x) in s) / len(s) if s else 0.0
- def sim(u, v): return importance_factor * avg_sim(list(product(G[u], G[v])))
+ def avg_sim(s):
+ return sum(newsim[w][x] for (w, x) in s) / len(s) if s else 0.0
+
+ def sim(u, v):
+ return importance_factor * avg_sim(list(product(G[u], G[v])))
for _ in range(max_iterations):
if prevsim and _is_close(prevsim, newsim, tolerance):
break
prevsim = newsim
- newsim = {u: {v: sim(u, v) if u is not v else 1
- for v in newsim[u]} for u in newsim}
+ newsim = {
+ u: {v: sim(u, v) if u is not v else 1 for v in newsim[u]} for u in newsim
+ }
if source is not None and target is not None:
return newsim[source][target]
@@ -1138,8 +1287,14 @@ def simrank_similarity(G, source=None, target=None, importance_factor=0.9,
return newsim
-def simrank_similarity_numpy(G, source=None, target=None, importance_factor=0.9,
- max_iterations=100, tolerance=1e-4):
+def simrank_similarity_numpy(
+ G,
+ source=None,
+ target=None,
+ importance_factor=0.9,
+ max_iterations=100,
+ tolerance=1e-4,
+):
"""Calculate SimRank of nodes in ``G`` using matrices with ``numpy``.
The SimRank algorithm for determining node similarity is defined in
@@ -1209,6 +1364,7 @@ def simrank_similarity_numpy(G, source=None, target=None, importance_factor=0.9,
# where C is the importance factor, A is the column normalized
# adjacency matrix, and I is the identity matrix.
import numpy as np
+
adjacency_matrix = nx.to_numpy_array(G)
# column-normalize the ``adjacency_matrix``
@@ -1218,7 +1374,8 @@ def simrank_similarity_numpy(G, source=None, target=None, importance_factor=0.9,
for _ in range(max_iterations):
prevsim = np.copy(newsim)
newsim = importance_factor * np.matmul(
- np.matmul(adjacency_matrix.T, prevsim), adjacency_matrix)
+ np.matmul(adjacency_matrix.T, prevsim), adjacency_matrix
+ )
np.fill_diagonal(newsim, 1.0)
if np.allclose(prevsim, newsim, atol=tolerance):
diff --git a/networkx/tests/test_all_random_functions.py b/networkx/tests/test_all_random_functions.py
index 52f2a111..0d862280 100644
--- a/networkx/tests/test_all_random_functions.py
+++ b/networkx/tests/test_all_random_functions.py
@@ -1,5 +1,6 @@
import pytest
-np = pytest.importorskip('numpy')
+
+np = pytest.importorskip("numpy")
import random
import networkx as nx
@@ -46,8 +47,8 @@ def run_all_random_functions(seed):
sizes = (20, 20, 10)
colors = [1, 2, 3]
G = nx.barbell_graph(12, 20)
- deg_sequence = in_degree_sequence = w = sequence = aseq = bseq = \
- [3, 2, 1, 3, 2, 1, 3, 2, 1, 2, 1, 2, 1]
+ deg_sequence = [3, 2, 1, 3, 2, 1, 3, 2, 1, 2, 1, 2, 1]
+ in_degree_sequence = w = sequence = aseq = bseq = deg_sequence
# print("starting...")
t(nx.maximal_independent_set, G, seed=seed)
@@ -81,43 +82,58 @@ def run_all_random_functions(seed):
t(nx.spectral_graph_forge, G, alpha, seed=seed)
t(nx.algorithms.community.asyn_fluidc, G, k, max_iter=1, seed=seed)
- t(nx.algorithms.connectivity.edge_augmentation.greedy_k_edge_augmentation,
- G, k, seed=seed)
+ t(
+ nx.algorithms.connectivity.edge_augmentation.greedy_k_edge_augmentation,
+ G,
+ k,
+ seed=seed,
+ )
t(nx.algorithms.coloring.strategy_random_sequential, G, colors, seed=seed)
- cs = ['d', 'i', 'i', 'd', 'd', 'i']
+ cs = ["d", "i", "i", "d", "d", "i"]
t(threshold.swap_d, cs, seed=seed)
t(nx.configuration_model, deg_sequence, seed=seed)
- t(nx.directed_configuration_model,
- in_degree_sequence, in_degree_sequence, seed=seed)
+ t(
+ nx.directed_configuration_model,
+ in_degree_sequence,
+ in_degree_sequence,
+ seed=seed,
+ )
t(nx.expected_degree_graph, w, seed=seed)
t(nx.random_degree_sequence_graph, sequence, seed=seed)
- joint_degrees = {1: {4: 1},
- 2: {2: 2, 3: 2, 4: 2},
- 3: {2: 2, 4: 1},
- 4: {1: 1, 2: 2, 3: 1}}
+ joint_degrees = {
+ 1: {4: 1},
+ 2: {2: 2, 3: 2, 4: 2},
+ 3: {2: 2, 4: 1},
+ 4: {1: 1, 2: 2, 3: 1},
+ }
t(nx.joint_degree_graph, joint_degrees, seed=seed)
- joint_degree_sequence = [(1, 0), (1, 0), (1, 0), (2, 0), (1, 0), (2, 1),
- (0, 1), (0, 1)]
+ joint_degree_sequence = [
+ (1, 0),
+ (1, 0),
+ (1, 0),
+ (2, 0),
+ (1, 0),
+ (2, 1),
+ (0, 1),
+ (0, 1),
+ ]
t(nx.random_clustered_graph, joint_degree_sequence, seed=seed)
- constructor = [(3, 3, .5), (10, 10, .7)]
+ constructor = [(3, 3, 0.5), (10, 10, 0.7)]
t(nx.random_shell_graph, constructor, seed=seed)
mapping = {1: 0.4, 2: 0.3, 3: 0.3}
t(nx.utils.random_weighted_sample, mapping, k, seed=seed)
t(nx.utils.weighted_choice, mapping, seed=seed)
t(nx.algorithms.bipartite.configuration_model, aseq, bseq, seed=seed)
- t(nx.algorithms.bipartite.preferential_attachment_graph,
- aseq, p, seed=seed)
+ t(nx.algorithms.bipartite.preferential_attachment_graph, aseq, p, seed=seed)
def kernel_integral(u, w, z):
- return (z - w)
+ return z - w
t(nx.random_kernel_graph, n, kernel_integral, seed=seed)
sizes = [75, 75, 300]
- probs = [[0.25, 0.05, 0.02],
- [0.05, 0.35, 0.07],
- [0.02, 0.07, 0.40]]
+ probs = [[0.25, 0.05, 0.02], [0.05, 0.35, 0.07], [0.02, 0.07, 0.40]]
t(nx.stochastic_block_model, sizes, probs, seed=seed)
t(nx.random_partition_graph, sizes, p_in, p_out, seed=seed)
@@ -163,13 +179,22 @@ def run_all_random_functions(seed):
t(nx.random_tree, n, seed=seed)
t(nx.utils.powerlaw_sequence, n, seed=seed)
t(nx.utils.zipf_rv, 2.3, seed=seed)
- cdist = [.2, .4, .5, .7, .9, 1.0]
+ cdist = [0.2, 0.4, 0.5, 0.7, 0.9, 1.0]
t(nx.utils.discrete_sequence, n, cdistribution=cdist, seed=seed)
t(nx.algorithms.bipartite.random_graph, n, m, p, seed=seed)
t(nx.algorithms.bipartite.gnmk_random_graph, n, m, k, seed=seed)
LFR = nx.generators.LFR_benchmark_graph
- t(LFR, 25, 3, 1.5, 0.1, average_degree=3, min_community=10,
- seed=seed, max_community=20)
+ t(
+ LFR,
+ 25,
+ 3,
+ 1.5,
+ 0.1,
+ average_degree=3,
+ min_community=10,
+ seed=seed,
+ max_community=20,
+ )
t(nx.random_internet_as_graph, n, seed=seed)
# print("done")
@@ -193,14 +218,15 @@ def test_rng_interface():
# check that both global RNGs are unaffected
after_np_rv = np.random.rand()
-# if np_rv != after_np_rv:
-# print(np_rv, after_np_rv, "don't match np!")
+ # if np_rv != after_np_rv:
+ # print(np_rv, after_np_rv, "don't match np!")
assert np_rv == after_np_rv
after_py_rv = random.random()
-# if py_rv != after_py_rv:
-# print(py_rv, after_py_rv, "don't match py!")
+ # if py_rv != after_py_rv:
+ # print(py_rv, after_py_rv, "don't match py!")
assert py_rv == after_py_rv
+
# print("\nDone testing seed:", seed)
# test_rng_interface()
diff --git a/networkx/tests/test_convert_pandas.py b/networkx/tests/test_convert_pandas.py
index 0744b100..f93af843 100644
--- a/networkx/tests/test_convert_pandas.py
+++ b/networkx/tests/test_convert_pandas.py
@@ -1,24 +1,23 @@
import pytest
+
pd = pytest.importorskip("pandas")
import networkx as nx
-from networkx.testing import assert_nodes_equal, assert_edges_equal, \
- assert_graphs_equal
+from networkx.testing import assert_nodes_equal, assert_edges_equal, assert_graphs_equal
class TestConvertPandas(object):
def setup_method(self):
self.rng = pd.np.random.RandomState(seed=5)
ints = self.rng.randint(1, 11, size=(3, 2))
- a = ['A', 'B', 'C']
- b = ['D', 'A', 'E']
- df = pd.DataFrame(ints, columns=['weight', 'cost'])
+ a = ["A", "B", "C"]
+ b = ["D", "A", "E"]
+ df = pd.DataFrame(ints, columns=["weight", "cost"])
df[0] = a # Column label 0 (int)
- df['b'] = b # Column label 'b' (str)
+ df["b"] = b # Column label 'b' (str)
self.df = df
- mdf = pd.DataFrame([[4, 16, 'A', 'D']],
- columns=['weight', 'cost', 0, 'b'])
+ mdf = pd.DataFrame([[4, 16, "A", "D"]], columns=["weight", "cost", 0, "b"])
self.mdf = df.append(mdf)
def test_exceptions(self):
@@ -26,98 +25,128 @@ class TestConvertPandas(object):
pytest.raises(nx.NetworkXError, nx.to_networkx_graph, G)
G = pd.DataFrame(["a", 0.0]) # elist
pytest.raises(nx.NetworkXError, nx.to_networkx_graph, G)
- df = pd.DataFrame([[1, 1], [1, 0]], dtype=int,
- index=[1, 2], columns=["a", "b"])
+ df = pd.DataFrame([[1, 1], [1, 0]], dtype=int, index=[1, 2], columns=["a", "b"])
pytest.raises(nx.NetworkXError, nx.from_pandas_adjacency, df)
def test_from_edgelist_all_attr(self):
- Gtrue = nx.Graph([('E', 'C', {'cost': 9, 'weight': 10}),
- ('B', 'A', {'cost': 1, 'weight': 7}),
- ('A', 'D', {'cost': 7, 'weight': 4})])
- G = nx.from_pandas_edgelist(self.df, 0, 'b', True)
+ Gtrue = nx.Graph(
+ [
+ ("E", "C", {"cost": 9, "weight": 10}),
+ ("B", "A", {"cost": 1, "weight": 7}),
+ ("A", "D", {"cost": 7, "weight": 4}),
+ ]
+ )
+ G = nx.from_pandas_edgelist(self.df, 0, "b", True)
assert_graphs_equal(G, Gtrue)
# MultiGraph
MGtrue = nx.MultiGraph(Gtrue)
- MGtrue.add_edge('A', 'D', cost=16, weight=4)
- MG = nx.from_pandas_edgelist(self.mdf, 0, 'b', True, nx.MultiGraph())
+ MGtrue.add_edge("A", "D", cost=16, weight=4)
+ MG = nx.from_pandas_edgelist(self.mdf, 0, "b", True, nx.MultiGraph())
assert_graphs_equal(MG, MGtrue)
def test_from_edgelist_multi_attr(self):
- Gtrue = nx.Graph([('E', 'C', {'cost': 9, 'weight': 10}),
- ('B', 'A', {'cost': 1, 'weight': 7}),
- ('A', 'D', {'cost': 7, 'weight': 4})])
- G = nx.from_pandas_edgelist(self.df, 0, 'b', ['weight', 'cost'])
+ Gtrue = nx.Graph(
+ [
+ ("E", "C", {"cost": 9, "weight": 10}),
+ ("B", "A", {"cost": 1, "weight": 7}),
+ ("A", "D", {"cost": 7, "weight": 4}),
+ ]
+ )
+ G = nx.from_pandas_edgelist(self.df, 0, "b", ["weight", "cost"])
assert_graphs_equal(G, Gtrue)
def test_from_edgelist_multi_attr_incl_target(self):
- Gtrue = nx.Graph([('E', 'C', {0: 'C', 'b': 'E', 'weight': 10}),
- ('B', 'A', {0: 'B', 'b': 'A', 'weight': 7}),
- ('A', 'D', {0: 'A', 'b': 'D', 'weight': 4})])
- G = nx.from_pandas_edgelist(self.df, 0, 'b', [0, 'b', 'weight'])
+ Gtrue = nx.Graph(
+ [
+ ("E", "C", {0: "C", "b": "E", "weight": 10}),
+ ("B", "A", {0: "B", "b": "A", "weight": 7}),
+ ("A", "D", {0: "A", "b": "D", "weight": 4}),
+ ]
+ )
+ G = nx.from_pandas_edgelist(self.df, 0, "b", [0, "b", "weight"])
assert_graphs_equal(G, Gtrue)
def test_from_edgelist_multidigraph_and_edge_attr(self):
# example from issue #2374
- edges = [('X1', 'X4', {'Co': 'zA', 'Mi': 0, 'St': 'X1'}),
- ('X1', 'X4', {'Co': 'zB', 'Mi': 54, 'St': 'X2'}),
- ('X1', 'X4', {'Co': 'zB', 'Mi': 49, 'St': 'X3'}),
- ('X1', 'X4', {'Co': 'zB', 'Mi': 44, 'St': 'X4'}),
- ('Y1', 'Y3', {'Co': 'zC', 'Mi': 0, 'St': 'Y1'}),
- ('Y1', 'Y3', {'Co': 'zC', 'Mi': 34, 'St': 'Y2'}),
- ('Y1', 'Y3', {'Co': 'zC', 'Mi': 29, 'St': 'X2'}),
- ('Y1', 'Y3', {'Co': 'zC', 'Mi': 24, 'St': 'Y3'}),
- ('Z1', 'Z3', {'Co': 'zD', 'Mi': 0, 'St': 'Z1'}),
- ('Z1', 'Z3', {'Co': 'zD', 'Mi': 14, 'St': 'X3'})]
+ edges = [
+ ("X1", "X4", {"Co": "zA", "Mi": 0, "St": "X1"}),
+ ("X1", "X4", {"Co": "zB", "Mi": 54, "St": "X2"}),
+ ("X1", "X4", {"Co": "zB", "Mi": 49, "St": "X3"}),
+ ("X1", "X4", {"Co": "zB", "Mi": 44, "St": "X4"}),
+ ("Y1", "Y3", {"Co": "zC", "Mi": 0, "St": "Y1"}),
+ ("Y1", "Y3", {"Co": "zC", "Mi": 34, "St": "Y2"}),
+ ("Y1", "Y3", {"Co": "zC", "Mi": 29, "St": "X2"}),
+ ("Y1", "Y3", {"Co": "zC", "Mi": 24, "St": "Y3"}),
+ ("Z1", "Z3", {"Co": "zD", "Mi": 0, "St": "Z1"}),
+ ("Z1", "Z3", {"Co": "zD", "Mi": 14, "St": "X3"}),
+ ]
Gtrue = nx.MultiDiGraph(edges)
- df = pd.DataFrame.from_dict({
- 'O': ['X1', 'X1', 'X1', 'X1', 'Y1', 'Y1', 'Y1', 'Y1', 'Z1', 'Z1'],
- 'D': ['X4', 'X4', 'X4', 'X4', 'Y3', 'Y3', 'Y3', 'Y3', 'Z3', 'Z3'],
- 'St': ['X1', 'X2', 'X3', 'X4', 'Y1', 'Y2', 'X2', 'Y3', 'Z1', 'X3'],
- 'Co': ['zA', 'zB', 'zB', 'zB', 'zC', 'zC', 'zC', 'zC', 'zD', 'zD'],
- 'Mi': [0, 54, 49, 44, 0, 34, 29, 24, 0, 14]})
- G1 = nx.from_pandas_edgelist(df, source='O', target='D',
- edge_attr=True,
- create_using=nx.MultiDiGraph)
- G2 = nx.from_pandas_edgelist(df, source='O', target='D',
- edge_attr=['St', 'Co', 'Mi'],
- create_using=nx.MultiDiGraph)
+ df = pd.DataFrame.from_dict(
+ {
+ "O": ["X1", "X1", "X1", "X1", "Y1", "Y1", "Y1", "Y1", "Z1", "Z1"],
+ "D": ["X4", "X4", "X4", "X4", "Y3", "Y3", "Y3", "Y3", "Z3", "Z3"],
+ "St": ["X1", "X2", "X3", "X4", "Y1", "Y2", "X2", "Y3", "Z1", "X3"],
+ "Co": ["zA", "zB", "zB", "zB", "zC", "zC", "zC", "zC", "zD", "zD"],
+ "Mi": [0, 54, 49, 44, 0, 34, 29, 24, 0, 14],
+ }
+ )
+ G1 = nx.from_pandas_edgelist(
+ df, source="O", target="D", edge_attr=True, create_using=nx.MultiDiGraph
+ )
+ G2 = nx.from_pandas_edgelist(
+ df,
+ source="O",
+ target="D",
+ edge_attr=["St", "Co", "Mi"],
+ create_using=nx.MultiDiGraph,
+ )
assert_graphs_equal(G1, Gtrue)
assert_graphs_equal(G2, Gtrue)
def test_from_edgelist_one_attr(self):
- Gtrue = nx.Graph([('E', 'C', {'weight': 10}),
- ('B', 'A', {'weight': 7}),
- ('A', 'D', {'weight': 4})])
- G = nx.from_pandas_edgelist(self.df, 0, 'b', 'weight')
+ Gtrue = nx.Graph(
+ [
+ ("E", "C", {"weight": 10}),
+ ("B", "A", {"weight": 7}),
+ ("A", "D", {"weight": 4}),
+ ]
+ )
+ G = nx.from_pandas_edgelist(self.df, 0, "b", "weight")
assert_graphs_equal(G, Gtrue)
def test_from_edgelist_int_attr_name(self):
# note: this also tests that edge_attr can be `source`
- Gtrue = nx.Graph([('E', 'C', {0: 'C'}),
- ('B', 'A', {0: 'B'}),
- ('A', 'D', {0: 'A'})])
- G = nx.from_pandas_edgelist(self.df, 0, 'b', 0)
+ Gtrue = nx.Graph(
+ [("E", "C", {0: "C"}), ("B", "A", {0: "B"}), ("A", "D", {0: "A"})]
+ )
+ G = nx.from_pandas_edgelist(self.df, 0, "b", 0)
assert_graphs_equal(G, Gtrue)
def test_from_edgelist_invalid_attr(self):
- pytest.raises(nx.NetworkXError, nx.from_pandas_edgelist,
- self.df, 0, 'b', 'misspell')
- pytest.raises(nx.NetworkXError, nx.from_pandas_edgelist,
- self.df, 0, 'b', 1)
+ pytest.raises(
+ nx.NetworkXError, nx.from_pandas_edgelist, self.df, 0, "b", "misspell"
+ )
+ pytest.raises(nx.NetworkXError, nx.from_pandas_edgelist, self.df, 0, "b", 1)
# see Issue #3562
- edgeframe = pd.DataFrame([[0, 1], [1, 2], [2, 0]], columns=['s', 't'])
- pytest.raises(nx.NetworkXError, nx.from_pandas_edgelist,
- edgeframe, 's', 't', True)
- pytest.raises(nx.NetworkXError, nx.from_pandas_edgelist,
- edgeframe, 's', 't', 'weight')
- pytest.raises(nx.NetworkXError, nx.from_pandas_edgelist,
- edgeframe, 's', 't', ['weight', 'size'])
+ edgeframe = pd.DataFrame([[0, 1], [1, 2], [2, 0]], columns=["s", "t"])
+ pytest.raises(
+ nx.NetworkXError, nx.from_pandas_edgelist, edgeframe, "s", "t", True
+ )
+ pytest.raises(
+ nx.NetworkXError, nx.from_pandas_edgelist, edgeframe, "s", "t", "weight"
+ )
+ pytest.raises(
+ nx.NetworkXError,
+ nx.from_pandas_edgelist,
+ edgeframe,
+ "s",
+ "t",
+ ["weight", "size"],
+ )
def test_from_edgelist_no_attr(self):
- Gtrue = nx.Graph([('E', 'C', {}),
- ('B', 'A', {}),
- ('A', 'D', {})])
- G = nx.from_pandas_edgelist(self.df, 0, 'b',)
+ Gtrue = nx.Graph([("E", "C", {}), ("B", "A", {}), ("A", "D", {})])
+ G = nx.from_pandas_edgelist(self.df, 0, "b")
assert_graphs_equal(G, Gtrue)
def test_from_edgelist(self):
@@ -129,11 +158,9 @@ class TestConvertPandas(object):
edgelist = nx.to_edgelist(G)
source = [s for s, t, d in edgelist]
target = [t for s, t, d in edgelist]
- weight = [d['weight'] for s, t, d in edgelist]
- edges = pd.DataFrame({'source': source,
- 'target': target,
- 'weight': weight})
- GG = nx.from_pandas_edgelist(edges, edge_attr='weight')
+ weight = [d["weight"] for s, t, d in edgelist]
+ edges = pd.DataFrame({"source": source, "target": target, "weight": weight})
+ GG = nx.from_pandas_edgelist(edges, edge_attr="weight")
assert_nodes_equal(G.nodes(), GG.nodes())
assert_edges_equal(G.edges(), GG.edges())
GW = nx.to_networkx_graph(edges, create_using=nx.Graph)
@@ -142,8 +169,9 @@ class TestConvertPandas(object):
def test_from_adjacency(self):
nodelist = [1, 2]
- dftrue = pd.DataFrame([[1, 1], [1, 0]], dtype=int,
- index=nodelist, columns=nodelist)
+ dftrue = pd.DataFrame(
+ [[1, 1], [1, 0]], dtype=int, index=nodelist, columns=nodelist
+ )
G = nx.Graph([(1, 1), (1, 2)])
df = nx.to_pandas_adjacency(G, dtype=int)
pd.testing.assert_frame_equal(df, dftrue)
@@ -155,7 +183,7 @@ class TestConvertPandas(object):
G = nx.from_pandas_edgelist(df)
assert_graphs_equal(Gtrue, G)
# adjacency
- adj = {1: {1: {'weight': 1}, 2: {'weight': 1}}, 2: {1: {'weight': 1}}}
+ adj = {1: {1: {"weight": 1}, 2: {"weight": 1}}, 2: {1: {"weight": 1}}}
Gtrue = nx.Graph(adj)
df = nx.to_pandas_adjacency(Gtrue, dtype=int)
G = nx.from_pandas_adjacency(df)
@@ -163,9 +191,11 @@ class TestConvertPandas(object):
def test_from_adjacency_named(self):
# example from issue #3105
- data = {"A": {"A": 0, "B": 0, "C": 0},
- "B": {"A": 1, "B": 0, "C": 0},
- "C": {"A": 0, "B": 1, "C": 0}}
+ data = {
+ "A": {"A": 0, "B": 0, "C": 0},
+ "B": {"A": 1, "B": 0, "C": 0},
+ "C": {"A": 0, "B": 1, "C": 0},
+ }
dftrue = pd.DataFrame(data)
df = dftrue[["A", "C", "B"]]
G = nx.from_pandas_adjacency(df, create_using=nx.DiGraph())