rm CondaPkg environment
This commit is contained in:
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.
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.
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.
@@ -2,7 +2,6 @@ import networkx as nx
|
||||
|
||||
|
||||
def test_is_at_free():
|
||||
|
||||
is_at_free = nx.asteroidal.is_at_free
|
||||
|
||||
cycle = nx.cycle_graph(6)
|
||||
|
||||
@@ -89,22 +89,22 @@ class TestMCS:
|
||||
frozenset([2, 3, 4]),
|
||||
frozenset([3, 4, 5, 6]),
|
||||
}
|
||||
assert {c for c in nx.chordal_graph_cliques(self.chordal_G)} == cliques
|
||||
assert set(nx.chordal_graph_cliques(self.chordal_G)) == cliques
|
||||
with pytest.raises(nx.NetworkXError, match="Input graph is not chordal"):
|
||||
{c for c in nx.chordal_graph_cliques(self.non_chordal_G)}
|
||||
set(nx.chordal_graph_cliques(self.non_chordal_G))
|
||||
with pytest.raises(nx.NetworkXError, match="Input graph is not chordal"):
|
||||
{c for c in nx.chordal_graph_cliques(self.self_loop_G)}
|
||||
set(nx.chordal_graph_cliques(self.self_loop_G))
|
||||
|
||||
def test_chordal_find_cliques_path(self):
|
||||
G = nx.path_graph(10)
|
||||
cliqueset = nx.chordal_graph_cliques(G)
|
||||
for (u, v) in G.edges():
|
||||
for u, v in G.edges():
|
||||
assert frozenset([u, v]) in cliqueset or frozenset([v, u]) in cliqueset
|
||||
|
||||
def test_chordal_find_cliquesCC(self):
|
||||
cliques = {frozenset([1, 2, 3]), frozenset([2, 3, 4]), frozenset([3, 4, 5, 6])}
|
||||
cgc = nx.chordal_graph_cliques
|
||||
assert {c for c in cgc(self.connected_chordal_G)} == cliques
|
||||
assert set(cgc(self.connected_chordal_G)) == cliques
|
||||
|
||||
def test_complete_to_chordal_graph(self):
|
||||
fgrg = nx.fast_gnp_random_graph
|
||||
|
||||
@@ -69,80 +69,96 @@ class TestCliques:
|
||||
|
||||
def test_clique_number(self):
|
||||
G = self.G
|
||||
assert nx.graph_clique_number(G) == 4
|
||||
assert nx.graph_clique_number(G, cliques=self.cl) == 4
|
||||
with pytest.deprecated_call():
|
||||
assert nx.graph_clique_number(G) == 4
|
||||
with pytest.deprecated_call():
|
||||
assert nx.graph_clique_number(G, cliques=self.cl) == 4
|
||||
|
||||
def test_clique_number2(self):
|
||||
G = nx.Graph()
|
||||
G.add_nodes_from([1, 2, 3])
|
||||
assert nx.graph_clique_number(G) == 1
|
||||
with pytest.deprecated_call():
|
||||
assert nx.graph_clique_number(G) == 1
|
||||
|
||||
def test_clique_number3(self):
|
||||
G = nx.Graph()
|
||||
assert nx.graph_clique_number(G) == 0
|
||||
with pytest.deprecated_call():
|
||||
assert nx.graph_clique_number(G) == 0
|
||||
|
||||
def test_number_of_cliques(self):
|
||||
G = self.G
|
||||
assert nx.graph_number_of_cliques(G) == 5
|
||||
assert nx.graph_number_of_cliques(G, cliques=self.cl) == 5
|
||||
assert nx.number_of_cliques(G, 1) == 1
|
||||
assert list(nx.number_of_cliques(G, [1]).values()) == [1]
|
||||
assert list(nx.number_of_cliques(G, [1, 2]).values()) == [1, 2]
|
||||
assert nx.number_of_cliques(G, [1, 2]) == {1: 1, 2: 2}
|
||||
assert nx.number_of_cliques(G, 2) == 2
|
||||
assert nx.number_of_cliques(G) == {
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 1,
|
||||
4: 2,
|
||||
5: 1,
|
||||
6: 2,
|
||||
7: 1,
|
||||
8: 1,
|
||||
9: 1,
|
||||
10: 1,
|
||||
11: 1,
|
||||
}
|
||||
assert nx.number_of_cliques(G, nodes=list(G)) == {
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 1,
|
||||
4: 2,
|
||||
5: 1,
|
||||
6: 2,
|
||||
7: 1,
|
||||
8: 1,
|
||||
9: 1,
|
||||
10: 1,
|
||||
11: 1,
|
||||
}
|
||||
assert nx.number_of_cliques(G, nodes=[2, 3, 4]) == {2: 2, 3: 1, 4: 2}
|
||||
assert nx.number_of_cliques(G, cliques=self.cl) == {
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 1,
|
||||
4: 2,
|
||||
5: 1,
|
||||
6: 2,
|
||||
7: 1,
|
||||
8: 1,
|
||||
9: 1,
|
||||
10: 1,
|
||||
11: 1,
|
||||
}
|
||||
assert nx.number_of_cliques(G, list(G), cliques=self.cl) == {
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 1,
|
||||
4: 2,
|
||||
5: 1,
|
||||
6: 2,
|
||||
7: 1,
|
||||
8: 1,
|
||||
9: 1,
|
||||
10: 1,
|
||||
11: 1,
|
||||
}
|
||||
with pytest.deprecated_call():
|
||||
assert nx.graph_number_of_cliques(G) == 5
|
||||
with pytest.deprecated_call():
|
||||
assert nx.graph_number_of_cliques(G, cliques=self.cl) == 5
|
||||
with pytest.deprecated_call():
|
||||
assert nx.number_of_cliques(G, 1) == 1
|
||||
with pytest.deprecated_call():
|
||||
assert list(nx.number_of_cliques(G, [1]).values()) == [1]
|
||||
with pytest.deprecated_call():
|
||||
assert list(nx.number_of_cliques(G, [1, 2]).values()) == [1, 2]
|
||||
with pytest.deprecated_call():
|
||||
assert nx.number_of_cliques(G, [1, 2]) == {1: 1, 2: 2}
|
||||
with pytest.deprecated_call():
|
||||
assert nx.number_of_cliques(G, 2) == 2
|
||||
with pytest.deprecated_call():
|
||||
assert nx.number_of_cliques(G) == {
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 1,
|
||||
4: 2,
|
||||
5: 1,
|
||||
6: 2,
|
||||
7: 1,
|
||||
8: 1,
|
||||
9: 1,
|
||||
10: 1,
|
||||
11: 1,
|
||||
}
|
||||
with pytest.deprecated_call():
|
||||
assert nx.number_of_cliques(G, nodes=list(G)) == {
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 1,
|
||||
4: 2,
|
||||
5: 1,
|
||||
6: 2,
|
||||
7: 1,
|
||||
8: 1,
|
||||
9: 1,
|
||||
10: 1,
|
||||
11: 1,
|
||||
}
|
||||
with pytest.deprecated_call():
|
||||
assert nx.number_of_cliques(G, nodes=[2, 3, 4]) == {2: 2, 3: 1, 4: 2}
|
||||
with pytest.deprecated_call():
|
||||
assert nx.number_of_cliques(G, cliques=self.cl) == {
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 1,
|
||||
4: 2,
|
||||
5: 1,
|
||||
6: 2,
|
||||
7: 1,
|
||||
8: 1,
|
||||
9: 1,
|
||||
10: 1,
|
||||
11: 1,
|
||||
}
|
||||
with pytest.deprecated_call():
|
||||
assert nx.number_of_cliques(G, list(G), cliques=self.cl) == {
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 1,
|
||||
4: 2,
|
||||
5: 1,
|
||||
6: 2,
|
||||
7: 1,
|
||||
8: 1,
|
||||
9: 1,
|
||||
10: 1,
|
||||
11: 1,
|
||||
}
|
||||
|
||||
def test_node_clique_number(self):
|
||||
G = self.G
|
||||
@@ -182,23 +198,31 @@ class TestCliques:
|
||||
|
||||
def test_cliques_containing_node(self):
|
||||
G = self.G
|
||||
assert nx.cliques_containing_node(G, 1) == [[2, 6, 1, 3]]
|
||||
assert list(nx.cliques_containing_node(G, [1]).values()) == [[[2, 6, 1, 3]]]
|
||||
assert [
|
||||
sorted(c) for c in list(nx.cliques_containing_node(G, [1, 2]).values())
|
||||
] == [[[2, 6, 1, 3]], [[2, 6, 1, 3], [2, 6, 4]]]
|
||||
result = nx.cliques_containing_node(G, [1, 2])
|
||||
with pytest.deprecated_call():
|
||||
assert nx.cliques_containing_node(G, 1) == [[2, 6, 1, 3]]
|
||||
with pytest.deprecated_call():
|
||||
assert list(nx.cliques_containing_node(G, [1]).values()) == [[[2, 6, 1, 3]]]
|
||||
with pytest.deprecated_call():
|
||||
assert [
|
||||
sorted(c) for c in list(nx.cliques_containing_node(G, [1, 2]).values())
|
||||
] == [[[2, 6, 1, 3]], [[2, 6, 1, 3], [2, 6, 4]]]
|
||||
with pytest.deprecated_call():
|
||||
result = nx.cliques_containing_node(G, [1, 2])
|
||||
for k, v in result.items():
|
||||
result[k] = sorted(v)
|
||||
assert result == {1: [[2, 6, 1, 3]], 2: [[2, 6, 1, 3], [2, 6, 4]]}
|
||||
assert nx.cliques_containing_node(G, 1) == [[2, 6, 1, 3]]
|
||||
with pytest.deprecated_call():
|
||||
assert nx.cliques_containing_node(G, 1) == [[2, 6, 1, 3]]
|
||||
expected = [{2, 6, 1, 3}, {2, 6, 4}]
|
||||
answer = [set(c) for c in nx.cliques_containing_node(G, 2)]
|
||||
with pytest.deprecated_call():
|
||||
answer = [set(c) for c in nx.cliques_containing_node(G, 2)]
|
||||
assert answer in (expected, list(reversed(expected)))
|
||||
|
||||
answer = [set(c) for c in nx.cliques_containing_node(G, 2, cliques=self.cl)]
|
||||
with pytest.deprecated_call():
|
||||
answer = [set(c) for c in nx.cliques_containing_node(G, 2, cliques=self.cl)]
|
||||
assert answer in (expected, list(reversed(expected)))
|
||||
assert len(nx.cliques_containing_node(G)) == 11
|
||||
with pytest.deprecated_call():
|
||||
assert len(nx.cliques_containing_node(G)) == 11
|
||||
|
||||
def test_make_clique_bipartite(self):
|
||||
G = self.G
|
||||
@@ -233,6 +257,17 @@ class TestCliques:
|
||||
with pytest.raises(nx.NetworkXNotImplemented):
|
||||
next(nx.find_cliques(nx.DiGraph()))
|
||||
|
||||
def test_find_cliques_trivial(self):
|
||||
G = nx.Graph()
|
||||
assert sorted(nx.find_cliques(G)) == []
|
||||
assert sorted(nx.find_cliques_recursive(G)) == []
|
||||
|
||||
def test_make_max_clique_graph_create_using(self):
|
||||
G = nx.Graph([(1, 2), (3, 1), (4, 1), (5, 6)])
|
||||
E = nx.Graph([(0, 1), (0, 2), (1, 2)])
|
||||
E.add_node(3)
|
||||
assert nx.is_isomorphic(nx.make_max_clique_graph(G, create_using=nx.Graph), E)
|
||||
|
||||
|
||||
class TestEnumerateAllCliques:
|
||||
def test_paper_figure_4(self):
|
||||
|
||||
@@ -26,7 +26,6 @@ class TestCommunicability:
|
||||
assert answer[k1][k2] == pytest.approx(result[k1][k2], abs=1e-7)
|
||||
|
||||
def test_communicability2(self):
|
||||
|
||||
answer_orig = {
|
||||
("1", "1"): 1.6445956054135658,
|
||||
("1", "Albert"): 0.7430186221096251,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
from itertools import chain, islice, tee
|
||||
from random import shuffle
|
||||
|
||||
import pytest
|
||||
|
||||
import networkx
|
||||
@@ -68,16 +71,13 @@ class TestCycles:
|
||||
for c in cc:
|
||||
assert any(self.is_cyclic_permutation(c, rc) for rc in ca)
|
||||
|
||||
def test_simple_cycles_graph(self):
|
||||
with pytest.raises(nx.NetworkXNotImplemented):
|
||||
G = nx.Graph()
|
||||
c = sorted(nx.simple_cycles(G))
|
||||
|
||||
def test_unsortable(self):
|
||||
# TODO What does this test do? das 6/2013
|
||||
# this test ensures that graphs whose nodes without an intrinsic
|
||||
# ordering do not cause issues
|
||||
G = nx.DiGraph()
|
||||
nx.add_cycle(G, ["a", 1])
|
||||
c = list(nx.simple_cycles(G))
|
||||
assert len(c) == 1
|
||||
|
||||
def test_simple_cycles_small(self):
|
||||
G = nx.DiGraph()
|
||||
@@ -96,13 +96,6 @@ class TestCycles:
|
||||
G = nx.DiGraph()
|
||||
assert list(nx.simple_cycles(G)) == []
|
||||
|
||||
def test_complete_directed_graph(self):
|
||||
# see table 2 in Johnson's paper
|
||||
ncircuits = [1, 5, 20, 84, 409, 2365, 16064]
|
||||
for n, c in zip(range(2, 9), ncircuits):
|
||||
G = nx.DiGraph(nx.complete_graph(n))
|
||||
assert len(list(nx.simple_cycles(G))) == c
|
||||
|
||||
def worst_case_graph(self, k):
|
||||
# see figure 1 in Johnson's paper
|
||||
# this graph has exactly 3k simple cycles
|
||||
@@ -169,6 +162,522 @@ class TestCycles:
|
||||
assert any(self.is_cyclic_permutation(rc, c) for c in cc)
|
||||
|
||||
|
||||
def pairwise(iterable):
|
||||
a, b = tee(iterable)
|
||||
next(b, None)
|
||||
return zip(a, b)
|
||||
|
||||
|
||||
def cycle_edges(c):
|
||||
return pairwise(chain(c, islice(c, 1)))
|
||||
|
||||
|
||||
def directed_cycle_edgeset(c):
|
||||
return frozenset(cycle_edges(c))
|
||||
|
||||
|
||||
def undirected_cycle_edgeset(c):
|
||||
if len(c) == 1:
|
||||
return frozenset(cycle_edges(c))
|
||||
return frozenset(map(frozenset, cycle_edges(c)))
|
||||
|
||||
|
||||
def multigraph_cycle_edgeset(c):
|
||||
if len(c) <= 2:
|
||||
return frozenset(cycle_edges(c))
|
||||
else:
|
||||
return frozenset(map(frozenset, cycle_edges(c)))
|
||||
|
||||
|
||||
class TestCycleEnumeration:
|
||||
@staticmethod
|
||||
def K(n):
|
||||
return nx.complete_graph(n)
|
||||
|
||||
@staticmethod
|
||||
def D(n):
|
||||
return nx.complete_graph(n).to_directed()
|
||||
|
||||
@staticmethod
|
||||
def edgeset_function(g):
|
||||
if g.is_directed():
|
||||
return directed_cycle_edgeset
|
||||
elif g.is_multigraph():
|
||||
return multigraph_cycle_edgeset
|
||||
else:
|
||||
return undirected_cycle_edgeset
|
||||
|
||||
def check_cycle(self, g, c, es, cache, source, original_c, length_bound, chordless):
|
||||
if length_bound is not None and len(c) > length_bound:
|
||||
raise RuntimeError(
|
||||
f"computed cycle {original_c} exceeds length bound {length_bound}"
|
||||
)
|
||||
if source == "computed":
|
||||
if es in cache:
|
||||
raise RuntimeError(
|
||||
f"computed cycle {original_c} has already been found!"
|
||||
)
|
||||
else:
|
||||
cache[es] = tuple(original_c)
|
||||
else:
|
||||
if es in cache:
|
||||
cache.pop(es)
|
||||
else:
|
||||
raise RuntimeError(f"expected cycle {original_c} was not computed")
|
||||
|
||||
if not all(g.has_edge(*e) for e in es):
|
||||
raise RuntimeError(
|
||||
f"{source} claimed cycle {original_c} is not a cycle of g"
|
||||
)
|
||||
if chordless and len(g.subgraph(c).edges) > len(c):
|
||||
raise RuntimeError(f"{source} cycle {original_c} is not chordless")
|
||||
|
||||
def check_cycle_algorithm(
|
||||
self,
|
||||
g,
|
||||
expected_cycles,
|
||||
length_bound=None,
|
||||
chordless=False,
|
||||
algorithm=None,
|
||||
):
|
||||
if algorithm is None:
|
||||
algorithm = nx.chordless_cycles if chordless else nx.simple_cycles
|
||||
|
||||
# note: we shuffle the labels of g to rule out accidentally-correct
|
||||
# behavior which occurred during the development of chordless cycle
|
||||
# enumeration algorithms
|
||||
|
||||
relabel = list(range(len(g)))
|
||||
shuffle(relabel)
|
||||
label = dict(zip(g, relabel))
|
||||
unlabel = dict(zip(relabel, g))
|
||||
h = nx.relabel_nodes(g, label, copy=True)
|
||||
|
||||
edgeset = self.edgeset_function(h)
|
||||
|
||||
params = {}
|
||||
if length_bound is not None:
|
||||
params["length_bound"] = length_bound
|
||||
|
||||
cycle_cache = {}
|
||||
for c in algorithm(h, **params):
|
||||
original_c = [unlabel[x] for x in c]
|
||||
es = edgeset(c)
|
||||
self.check_cycle(
|
||||
h, c, es, cycle_cache, "computed", original_c, length_bound, chordless
|
||||
)
|
||||
|
||||
if isinstance(expected_cycles, int):
|
||||
if len(cycle_cache) != expected_cycles:
|
||||
raise RuntimeError(
|
||||
f"expected {expected_cycles} cycles, got {len(cycle_cache)}"
|
||||
)
|
||||
return
|
||||
for original_c in expected_cycles:
|
||||
c = [label[x] for x in original_c]
|
||||
es = edgeset(c)
|
||||
self.check_cycle(
|
||||
h, c, es, cycle_cache, "expected", original_c, length_bound, chordless
|
||||
)
|
||||
|
||||
if len(cycle_cache):
|
||||
for c in cycle_cache.values():
|
||||
raise RuntimeError(
|
||||
f"computed cycle {c} is valid but not in the expected cycle set!"
|
||||
)
|
||||
|
||||
def check_cycle_enumeration_integer_sequence(
|
||||
self,
|
||||
g_family,
|
||||
cycle_counts,
|
||||
length_bound=None,
|
||||
chordless=False,
|
||||
algorithm=None,
|
||||
):
|
||||
for g, num_cycles in zip(g_family, cycle_counts):
|
||||
self.check_cycle_algorithm(
|
||||
g,
|
||||
num_cycles,
|
||||
length_bound=length_bound,
|
||||
chordless=chordless,
|
||||
algorithm=algorithm,
|
||||
)
|
||||
|
||||
def test_directed_chordless_cycle_digons(self):
|
||||
g = nx.DiGraph()
|
||||
nx.add_cycle(g, range(5))
|
||||
nx.add_cycle(g, range(5)[::-1])
|
||||
g.add_edge(0, 0)
|
||||
expected_cycles = [(0,), (1, 2), (2, 3), (3, 4)]
|
||||
self.check_cycle_algorithm(g, expected_cycles, chordless=True)
|
||||
|
||||
self.check_cycle_algorithm(g, expected_cycles, chordless=True, length_bound=2)
|
||||
|
||||
expected_cycles = [c for c in expected_cycles if len(c) < 2]
|
||||
self.check_cycle_algorithm(g, expected_cycles, chordless=True, length_bound=1)
|
||||
|
||||
def test_directed_chordless_cycle_undirected(self):
|
||||
g = nx.DiGraph([(1, 2), (2, 3), (3, 4), (4, 5), (5, 0), (5, 1), (0, 2)])
|
||||
expected_cycles = [(0, 2, 3, 4, 5), (1, 2, 3, 4, 5)]
|
||||
self.check_cycle_algorithm(g, expected_cycles, chordless=True)
|
||||
|
||||
g = nx.DiGraph()
|
||||
nx.add_cycle(g, range(5))
|
||||
nx.add_cycle(g, range(4, 9))
|
||||
g.add_edge(7, 3)
|
||||
expected_cycles = [(0, 1, 2, 3, 4), (3, 4, 5, 6, 7), (4, 5, 6, 7, 8)]
|
||||
self.check_cycle_algorithm(g, expected_cycles, chordless=True)
|
||||
|
||||
g.add_edge(3, 7)
|
||||
expected_cycles = [(0, 1, 2, 3, 4), (3, 7), (4, 5, 6, 7, 8)]
|
||||
self.check_cycle_algorithm(g, expected_cycles, chordless=True)
|
||||
|
||||
expected_cycles = [(3, 7)]
|
||||
self.check_cycle_algorithm(g, expected_cycles, chordless=True, length_bound=4)
|
||||
|
||||
g.remove_edge(7, 3)
|
||||
expected_cycles = [(0, 1, 2, 3, 4), (4, 5, 6, 7, 8)]
|
||||
self.check_cycle_algorithm(g, expected_cycles, chordless=True)
|
||||
|
||||
g = nx.DiGraph((i, j) for i in range(10) for j in range(i))
|
||||
expected_cycles = []
|
||||
self.check_cycle_algorithm(g, expected_cycles, chordless=True)
|
||||
|
||||
def test_chordless_cycles_directed(self):
|
||||
G = nx.DiGraph()
|
||||
nx.add_cycle(G, range(5))
|
||||
nx.add_cycle(G, range(4, 12))
|
||||
expected = [[*range(5)], [*range(4, 12)]]
|
||||
self.check_cycle_algorithm(G, expected, chordless=True)
|
||||
self.check_cycle_algorithm(
|
||||
G, [c for c in expected if len(c) <= 5], length_bound=5, chordless=True
|
||||
)
|
||||
|
||||
G.add_edge(7, 3)
|
||||
expected.append([*range(3, 8)])
|
||||
self.check_cycle_algorithm(G, expected, chordless=True)
|
||||
self.check_cycle_algorithm(
|
||||
G, [c for c in expected if len(c) <= 5], length_bound=5, chordless=True
|
||||
)
|
||||
|
||||
G.add_edge(3, 7)
|
||||
expected[-1] = [7, 3]
|
||||
self.check_cycle_algorithm(G, expected, chordless=True)
|
||||
self.check_cycle_algorithm(
|
||||
G, [c for c in expected if len(c) <= 5], length_bound=5, chordless=True
|
||||
)
|
||||
|
||||
expected.pop()
|
||||
G.remove_edge(7, 3)
|
||||
self.check_cycle_algorithm(G, expected, chordless=True)
|
||||
self.check_cycle_algorithm(
|
||||
G, [c for c in expected if len(c) <= 5], length_bound=5, chordless=True
|
||||
)
|
||||
|
||||
def test_directed_chordless_cycle_diclique(self):
|
||||
g_family = [self.D(n) for n in range(10)]
|
||||
expected_cycles = [(n * n - n) // 2 for n in range(10)]
|
||||
self.check_cycle_enumeration_integer_sequence(
|
||||
g_family, expected_cycles, chordless=True
|
||||
)
|
||||
|
||||
expected_cycles = [(n * n - n) // 2 for n in range(10)]
|
||||
self.check_cycle_enumeration_integer_sequence(
|
||||
g_family, expected_cycles, length_bound=2
|
||||
)
|
||||
|
||||
def test_directed_chordless_loop_blockade(self):
|
||||
g = nx.DiGraph((i, i) for i in range(10))
|
||||
nx.add_cycle(g, range(10))
|
||||
expected_cycles = [(i,) for i in range(10)]
|
||||
self.check_cycle_algorithm(g, expected_cycles, chordless=True)
|
||||
|
||||
self.check_cycle_algorithm(g, expected_cycles, length_bound=1)
|
||||
|
||||
g = nx.MultiDiGraph(g)
|
||||
g.add_edges_from((i, i) for i in range(0, 10, 2))
|
||||
expected_cycles = [(i,) for i in range(1, 10, 2)]
|
||||
self.check_cycle_algorithm(g, expected_cycles, chordless=True)
|
||||
|
||||
def test_simple_cycles_notable_clique_sequences(self):
|
||||
# A000292: Number of labeled graphs on n+3 nodes that are triangles.
|
||||
g_family = [self.K(n) for n in range(2, 12)]
|
||||
expected = [0, 1, 4, 10, 20, 35, 56, 84, 120, 165, 220]
|
||||
self.check_cycle_enumeration_integer_sequence(
|
||||
g_family, expected, length_bound=3
|
||||
)
|
||||
|
||||
def triangles(g, **kwargs):
|
||||
yield from (c for c in nx.simple_cycles(g, **kwargs) if len(c) == 3)
|
||||
|
||||
# directed complete graphs have twice as many triangles thanks to reversal
|
||||
g_family = [self.D(n) for n in range(2, 12)]
|
||||
expected = [2 * e for e in expected]
|
||||
self.check_cycle_enumeration_integer_sequence(
|
||||
g_family, expected, length_bound=3, algorithm=triangles
|
||||
)
|
||||
|
||||
def four_cycles(g, **kwargs):
|
||||
yield from (c for c in nx.simple_cycles(g, **kwargs) if len(c) == 4)
|
||||
|
||||
# A050534: the number of 4-cycles in the complete graph K_{n+1}
|
||||
expected = [0, 0, 0, 3, 15, 45, 105, 210, 378, 630, 990]
|
||||
g_family = [self.K(n) for n in range(1, 12)]
|
||||
self.check_cycle_enumeration_integer_sequence(
|
||||
g_family, expected, length_bound=4, algorithm=four_cycles
|
||||
)
|
||||
|
||||
# directed complete graphs have twice as many 4-cycles thanks to reversal
|
||||
expected = [2 * e for e in expected]
|
||||
g_family = [self.D(n) for n in range(1, 15)]
|
||||
self.check_cycle_enumeration_integer_sequence(
|
||||
g_family, expected, length_bound=4, algorithm=four_cycles
|
||||
)
|
||||
|
||||
# A006231: the number of elementary circuits in a complete directed graph with n nodes
|
||||
expected = [0, 1, 5, 20, 84, 409, 2365]
|
||||
g_family = [self.D(n) for n in range(1, 8)]
|
||||
self.check_cycle_enumeration_integer_sequence(g_family, expected)
|
||||
|
||||
# A002807: Number of cycles in the complete graph on n nodes K_{n}.
|
||||
expected = [0, 0, 0, 1, 7, 37, 197, 1172]
|
||||
g_family = [self.K(n) for n in range(8)]
|
||||
self.check_cycle_enumeration_integer_sequence(g_family, expected)
|
||||
|
||||
def test_directed_chordless_cycle_parallel_multiedges(self):
|
||||
g = nx.MultiGraph()
|
||||
|
||||
nx.add_cycle(g, range(5))
|
||||
expected = [[*range(5)]]
|
||||
self.check_cycle_algorithm(g, expected, chordless=True)
|
||||
|
||||
nx.add_cycle(g, range(5))
|
||||
expected = [*cycle_edges(range(5))]
|
||||
self.check_cycle_algorithm(g, expected, chordless=True)
|
||||
|
||||
nx.add_cycle(g, range(5))
|
||||
expected = []
|
||||
self.check_cycle_algorithm(g, expected, chordless=True)
|
||||
|
||||
g = nx.MultiDiGraph()
|
||||
|
||||
nx.add_cycle(g, range(5))
|
||||
expected = [[*range(5)]]
|
||||
self.check_cycle_algorithm(g, expected, chordless=True)
|
||||
|
||||
nx.add_cycle(g, range(5))
|
||||
self.check_cycle_algorithm(g, [], chordless=True)
|
||||
|
||||
nx.add_cycle(g, range(5))
|
||||
self.check_cycle_algorithm(g, [], chordless=True)
|
||||
|
||||
g = nx.MultiDiGraph()
|
||||
|
||||
nx.add_cycle(g, range(5))
|
||||
nx.add_cycle(g, range(5)[::-1])
|
||||
expected = [*cycle_edges(range(5))]
|
||||
self.check_cycle_algorithm(g, expected, chordless=True)
|
||||
|
||||
nx.add_cycle(g, range(5))
|
||||
self.check_cycle_algorithm(g, [], chordless=True)
|
||||
|
||||
def test_chordless_cycles_graph(self):
|
||||
G = nx.Graph()
|
||||
nx.add_cycle(G, range(5))
|
||||
nx.add_cycle(G, range(4, 12))
|
||||
expected = [[*range(5)], [*range(4, 12)]]
|
||||
self.check_cycle_algorithm(G, expected, chordless=True)
|
||||
self.check_cycle_algorithm(
|
||||
G, [c for c in expected if len(c) <= 5], length_bound=5, chordless=True
|
||||
)
|
||||
|
||||
G.add_edge(7, 3)
|
||||
expected.append([*range(3, 8)])
|
||||
expected.append([4, 3, 7, 8, 9, 10, 11])
|
||||
self.check_cycle_algorithm(G, expected, chordless=True)
|
||||
self.check_cycle_algorithm(
|
||||
G, [c for c in expected if len(c) <= 5], length_bound=5, chordless=True
|
||||
)
|
||||
|
||||
def test_chordless_cycles_giant_hamiltonian(self):
|
||||
# ... o - e - o - e - o ... # o = odd, e = even
|
||||
# ... ---/ \-----/ \--- ... # <-- "long" edges
|
||||
#
|
||||
# each long edge belongs to exactly one triangle, and one giant cycle
|
||||
# of length n/2. The remaining edges each belong to a triangle
|
||||
|
||||
n = 1000
|
||||
assert n % 2 == 0
|
||||
G = nx.Graph()
|
||||
for v in range(n):
|
||||
if not v % 2:
|
||||
G.add_edge(v, (v + 2) % n)
|
||||
G.add_edge(v, (v + 1) % n)
|
||||
|
||||
expected = [[*range(0, n, 2)]] + [
|
||||
[x % n for x in range(i, i + 3)] for i in range(0, n, 2)
|
||||
]
|
||||
self.check_cycle_algorithm(G, expected, chordless=True)
|
||||
self.check_cycle_algorithm(
|
||||
G, [c for c in expected if len(c) <= 3], length_bound=3, chordless=True
|
||||
)
|
||||
|
||||
# ... o -> e -> o -> e -> o ... # o = odd, e = even
|
||||
# ... <---/ \---<---/ \---< ... # <-- "long" edges
|
||||
#
|
||||
# this time, we orient the short and long edges in opposition
|
||||
# the cycle structure of this graph is the same, but we need to reverse
|
||||
# the long one in our representation. Also, we need to drop the size
|
||||
# because our partitioning algorithm uses strongly connected components
|
||||
# instead of separating graphs by their strong articulation points
|
||||
|
||||
n = 100
|
||||
assert n % 2 == 0
|
||||
G = nx.DiGraph()
|
||||
for v in range(n):
|
||||
G.add_edge(v, (v + 1) % n)
|
||||
if not v % 2:
|
||||
G.add_edge((v + 2) % n, v)
|
||||
|
||||
expected = [[*range(n - 2, -2, -2)]] + [
|
||||
[x % n for x in range(i, i + 3)] for i in range(0, n, 2)
|
||||
]
|
||||
self.check_cycle_algorithm(G, expected, chordless=True)
|
||||
self.check_cycle_algorithm(
|
||||
G, [c for c in expected if len(c) <= 3], length_bound=3, chordless=True
|
||||
)
|
||||
|
||||
def test_simple_cycles_acyclic_tournament(self):
|
||||
n = 10
|
||||
G = nx.DiGraph((x, y) for x in range(n) for y in range(x))
|
||||
self.check_cycle_algorithm(G, [])
|
||||
self.check_cycle_algorithm(G, [], chordless=True)
|
||||
|
||||
for k in range(n + 1):
|
||||
self.check_cycle_algorithm(G, [], length_bound=k)
|
||||
self.check_cycle_algorithm(G, [], length_bound=k, chordless=True)
|
||||
|
||||
def test_simple_cycles_graph(self):
|
||||
testG = nx.cycle_graph(8)
|
||||
cyc1 = tuple(range(8))
|
||||
self.check_cycle_algorithm(testG, [cyc1])
|
||||
|
||||
testG.add_edge(4, -1)
|
||||
nx.add_path(testG, [3, -2, -3, -4])
|
||||
self.check_cycle_algorithm(testG, [cyc1])
|
||||
|
||||
testG.update(nx.cycle_graph(range(8, 16)))
|
||||
cyc2 = tuple(range(8, 16))
|
||||
self.check_cycle_algorithm(testG, [cyc1, cyc2])
|
||||
|
||||
testG.update(nx.cycle_graph(range(4, 12)))
|
||||
cyc3 = tuple(range(4, 12))
|
||||
expected = {
|
||||
(0, 1, 2, 3, 4, 5, 6, 7), # cyc1
|
||||
(8, 9, 10, 11, 12, 13, 14, 15), # cyc2
|
||||
(4, 5, 6, 7, 8, 9, 10, 11), # cyc3
|
||||
(4, 5, 6, 7, 8, 15, 14, 13, 12, 11), # cyc2 + cyc3
|
||||
(0, 1, 2, 3, 4, 11, 10, 9, 8, 7), # cyc1 + cyc3
|
||||
(0, 1, 2, 3, 4, 11, 12, 13, 14, 15, 8, 7), # cyc1 + cyc2 + cyc3
|
||||
}
|
||||
self.check_cycle_algorithm(testG, expected)
|
||||
assert len(expected) == (2**3 - 1) - 1 # 1 disjoint comb: cyc1 + cyc2
|
||||
|
||||
# Basis size = 5 (2 loops overlapping gives 5 small loops
|
||||
# E
|
||||
# / \ Note: A-F = 10-15
|
||||
# 1-2-3-4-5
|
||||
# / | | \ cyc1=012DAB -- left
|
||||
# 0 D F 6 cyc2=234E -- top
|
||||
# \ | | / cyc3=45678F -- right
|
||||
# B-A-9-8-7 cyc4=89AC -- bottom
|
||||
# \ / cyc5=234F89AD -- middle
|
||||
# C
|
||||
#
|
||||
# combinations of 5 basis elements: 2^5 - 1 (one includes no cycles)
|
||||
#
|
||||
# disjoint combs: (11 total) not simple cycles
|
||||
# Any pair not including cyc5 => choose(4, 2) = 6
|
||||
# Any triple not including cyc5 => choose(4, 3) = 4
|
||||
# Any quad not including cyc5 => choose(4, 4) = 1
|
||||
#
|
||||
# we expect 31 - 11 = 20 simple cycles
|
||||
#
|
||||
testG = nx.cycle_graph(12)
|
||||
testG.update(nx.cycle_graph([12, 10, 13, 2, 14, 4, 15, 8]).edges)
|
||||
expected = (2**5 - 1) - 11 # 11 disjoint combinations
|
||||
self.check_cycle_algorithm(testG, expected)
|
||||
|
||||
def test_simple_cycles_bounded(self):
|
||||
# iteratively construct a cluster of nested cycles running in the same direction
|
||||
# there should be one cycle of every length
|
||||
d = nx.DiGraph()
|
||||
expected = []
|
||||
for n in range(10):
|
||||
nx.add_cycle(d, range(n))
|
||||
expected.append(n)
|
||||
for k, e in enumerate(expected):
|
||||
self.check_cycle_algorithm(d, e, length_bound=k)
|
||||
|
||||
# iteratively construct a path of undirected cycles, connected at articulation
|
||||
# points. there should be one cycle of every length except 2: no digons
|
||||
g = nx.Graph()
|
||||
top = 0
|
||||
expected = []
|
||||
for n in range(10):
|
||||
expected.append(n if n < 2 else n - 1)
|
||||
if n == 2:
|
||||
# no digons in undirected graphs
|
||||
continue
|
||||
nx.add_cycle(g, range(top, top + n))
|
||||
top += n
|
||||
for k, e in enumerate(expected):
|
||||
self.check_cycle_algorithm(g, e, length_bound=k)
|
||||
|
||||
def test_simple_cycles_bound_corner_cases(self):
|
||||
G = nx.cycle_graph(4)
|
||||
DG = nx.cycle_graph(4, create_using=nx.DiGraph)
|
||||
assert list(nx.simple_cycles(G, length_bound=0)) == []
|
||||
assert list(nx.simple_cycles(DG, length_bound=0)) == []
|
||||
assert list(nx.chordless_cycles(G, length_bound=0)) == []
|
||||
assert list(nx.chordless_cycles(DG, length_bound=0)) == []
|
||||
|
||||
def test_simple_cycles_bound_error(self):
|
||||
with pytest.raises(ValueError):
|
||||
G = nx.DiGraph()
|
||||
for c in nx.simple_cycles(G, -1):
|
||||
assert False
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
G = nx.Graph()
|
||||
for c in nx.simple_cycles(G, -1):
|
||||
assert False
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
G = nx.Graph()
|
||||
for c in nx.chordless_cycles(G, -1):
|
||||
assert False
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
G = nx.DiGraph()
|
||||
for c in nx.chordless_cycles(G, -1):
|
||||
assert False
|
||||
|
||||
def test_chordless_cycles_clique(self):
|
||||
g_family = [self.K(n) for n in range(2, 15)]
|
||||
expected = [0, 1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364]
|
||||
self.check_cycle_enumeration_integer_sequence(
|
||||
g_family, expected, chordless=True
|
||||
)
|
||||
|
||||
# directed cliques have as many digons as undirected graphs have edges
|
||||
expected = [(n * n - n) // 2 for n in range(15)]
|
||||
g_family = [self.D(n) for n in range(15)]
|
||||
self.check_cycle_enumeration_integer_sequence(
|
||||
g_family, expected, chordless=True
|
||||
)
|
||||
|
||||
|
||||
# These tests might fail with hash randomization since they depend on
|
||||
# edge_dfs. For more information, see the comments in:
|
||||
# networkx/algorithms/traversal/tests/test_edgedfs.py
|
||||
@@ -349,7 +858,7 @@ class TestMinimumCycles:
|
||||
def test_complete_graph(self):
|
||||
cg = nx.complete_graph(5)
|
||||
mcb = minimum_cycle_basis(cg)
|
||||
assert all([len(cycle) == 3 for cycle in mcb])
|
||||
assert all(len(cycle) == 3 for cycle in mcb)
|
||||
|
||||
def test_tree_graph(self):
|
||||
tg = nx.balanced_tree(3, 3)
|
||||
|
||||
@@ -119,7 +119,7 @@ class TestDominanceFrontiers:
|
||||
# Software Practice & Experience, 4:110, 2001.
|
||||
edges = [(1, 2), (2, 1), (3, 2), (4, 1), (5, 3), (5, 4)]
|
||||
G = nx.DiGraph(edges)
|
||||
assert {u: df for u, df in nx.dominance_frontiers(G, 5).items()} == {
|
||||
assert dict(nx.dominance_frontiers(G, 5).items()) == {
|
||||
1: {2},
|
||||
2: {1},
|
||||
3: {2},
|
||||
|
||||
@@ -42,7 +42,7 @@ class TestAtlas:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
global atlas
|
||||
import networkx.generators.atlas as atlas
|
||||
from networkx.generators import atlas
|
||||
|
||||
cls.GAG = atlas.graph_atlas_g()
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class TestTreeLCA:
|
||||
|
||||
@staticmethod
|
||||
def assert_has_same_pairs(d1, d2):
|
||||
for (a, b) in ((min(pair), max(pair)) for pair in chain(d1, d2)):
|
||||
for a, b in ((min(pair), max(pair)) for pair in chain(d1, d2)):
|
||||
assert get_pair(d1, a, b) == get_pair(d2, a, b)
|
||||
|
||||
def test_tree_all_pairs_lca_default_root(self):
|
||||
|
||||
@@ -71,7 +71,7 @@ class TestHarmonicFunction:
|
||||
for i in label_removed:
|
||||
del G.nodes[i][label_name]
|
||||
predicted = node_classification.harmonic_function(G, label_name=label_name)
|
||||
label_not_removed = set(list(range(len(G)))) - label_removed
|
||||
label_not_removed = set(range(len(G))) - label_removed
|
||||
for i in label_not_removed:
|
||||
assert predicted[i] == G.nodes[i][label_name]
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ class Vector:
|
||||
return self.x * other.y < self.y * other.x
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
return self != other
|
||||
|
||||
def __le__(self, other):
|
||||
return not other < self
|
||||
|
||||
@@ -4,7 +4,6 @@ import networkx as nx
|
||||
|
||||
|
||||
class TestReciprocity:
|
||||
|
||||
# test overall reicprocity by passing whole graph
|
||||
def test_reciprocity_digraph(self):
|
||||
DG = nx.DiGraph([(1, 2), (2, 1)])
|
||||
|
||||
@@ -238,9 +238,9 @@ def test_hamiltonian_path():
|
||||
def test_cutoff_zero():
|
||||
G = nx.complete_graph(4)
|
||||
paths = nx.all_simple_paths(G, 0, 3, cutoff=0)
|
||||
assert list(list(p) for p in paths) == []
|
||||
assert [list(p) for p in paths] == []
|
||||
paths = nx.all_simple_paths(nx.MultiGraph(G), 0, 3, cutoff=0)
|
||||
assert list(list(p) for p in paths) == []
|
||||
assert [list(p) for p in paths] == []
|
||||
|
||||
|
||||
def test_source_missing():
|
||||
@@ -422,15 +422,15 @@ def test_hamiltonian__edge_path():
|
||||
G = nx.complete_graph(4)
|
||||
paths = hamiltonian_edge_path(G, 0)
|
||||
exact = [list(pairwise([0] + list(p))) for p in permutations([1, 2, 3], 3)]
|
||||
assert sorted(exact) == [p for p in sorted(paths)]
|
||||
assert sorted(exact) == sorted(paths)
|
||||
|
||||
|
||||
def test_edge_cutoff_zero():
|
||||
G = nx.complete_graph(4)
|
||||
paths = nx.all_simple_edge_paths(G, 0, 3, cutoff=0)
|
||||
assert list(list(p) for p in paths) == []
|
||||
assert [list(p) for p in paths] == []
|
||||
paths = nx.all_simple_edge_paths(nx.MultiGraph(G), 0, 3, cutoff=0)
|
||||
assert list(list(p) for p in paths) == []
|
||||
assert [list(p) for p in paths] == []
|
||||
|
||||
|
||||
def test_edge_source_missing():
|
||||
@@ -461,10 +461,10 @@ def test_shortest_simple_paths():
|
||||
def test_shortest_simple_paths_directed():
|
||||
G = nx.cycle_graph(7, create_using=nx.DiGraph())
|
||||
paths = nx.shortest_simple_paths(G, 0, 3)
|
||||
assert [path for path in paths] == [[0, 1, 2, 3]]
|
||||
assert list(paths) == [[0, 1, 2, 3]]
|
||||
|
||||
|
||||
def test_shortest_simple_paths_directed_with_weight_fucntion():
|
||||
def test_shortest_simple_paths_directed_with_weight_function():
|
||||
def cost(u, v, x):
|
||||
return 1
|
||||
|
||||
@@ -477,13 +477,13 @@ def test_shortest_simple_paths_directed_with_weight_fucntion():
|
||||
] == sorted(len(path) for path in nx.all_simple_paths(G, 1, 12))
|
||||
|
||||
|
||||
def test_shortest_simple_paths_with_weight_fucntion():
|
||||
def test_shortest_simple_paths_with_weight_function():
|
||||
def cost(u, v, x):
|
||||
return 1
|
||||
|
||||
G = nx.cycle_graph(7, create_using=nx.DiGraph())
|
||||
paths = nx.shortest_simple_paths(G, 0, 3, weight=cost)
|
||||
assert [path for path in paths] == [[0, 1, 2, 3]]
|
||||
assert list(paths) == [[0, 1, 2, 3]]
|
||||
|
||||
|
||||
def test_Greg_Bernstein():
|
||||
@@ -721,7 +721,7 @@ def test_bidirectional_dijksta_restricted():
|
||||
"s",
|
||||
"v",
|
||||
11,
|
||||
*_bidirectional_dijkstra(XG, "s", "v", ignore_edges=[("s", "x")])
|
||||
*_bidirectional_dijkstra(XG, "s", "v", ignore_edges=[("s", "x")]),
|
||||
)
|
||||
pytest.raises(
|
||||
nx.NetworkXNoPath,
|
||||
|
||||
@@ -4,6 +4,7 @@ import math
|
||||
import pytest
|
||||
|
||||
import networkx as nx
|
||||
from networkx.classes.tests import dispatch_interface
|
||||
|
||||
|
||||
class TestStructuralHoles:
|
||||
@@ -51,8 +52,11 @@ class TestStructuralHoles:
|
||||
("G", "C"): 10,
|
||||
}
|
||||
|
||||
def test_constraint_directed(self):
|
||||
constraint = nx.constraint(self.D)
|
||||
# This additionally tests the @nx._dispatch mechanism, treating
|
||||
# nx.mutual_weight as if it were a re-implementation from another package
|
||||
@pytest.mark.parametrize("wrapper", [lambda x: x, dispatch_interface.convert])
|
||||
def test_constraint_directed(self, wrapper):
|
||||
constraint = nx.constraint(wrapper(self.D))
|
||||
assert constraint[0] == pytest.approx(1.003, abs=1e-3)
|
||||
assert constraint[1] == pytest.approx(1.003, abs=1e-3)
|
||||
assert constraint[2] == pytest.approx(1.389, abs=1e-3)
|
||||
|
||||
@@ -253,7 +253,7 @@ class AbstractSNAP:
|
||||
node_labels = sorted(node_labels, key=lambda n: sorted(G.nodes[n]["group"])[0])
|
||||
node_labels.sort()
|
||||
|
||||
label_mapping = dict()
|
||||
label_mapping = {}
|
||||
for index, node in enumerate(node_labels):
|
||||
label = "Supernode-%s" % index
|
||||
label_mapping[node] = label
|
||||
@@ -277,18 +277,18 @@ class TestSNAPNoEdgeTypes(AbstractSNAP):
|
||||
|
||||
def build_original_graph(self):
|
||||
nodes = {
|
||||
"A": dict(color="Red"),
|
||||
"B": dict(color="Red"),
|
||||
"C": dict(color="Red"),
|
||||
"D": dict(color="Red"),
|
||||
"E": dict(color="Blue"),
|
||||
"F": dict(color="Blue"),
|
||||
"G": dict(color="Blue"),
|
||||
"H": dict(color="Blue"),
|
||||
"I": dict(color="Yellow"),
|
||||
"J": dict(color="Yellow"),
|
||||
"K": dict(color="Yellow"),
|
||||
"L": dict(color="Yellow"),
|
||||
"A": {"color": "Red"},
|
||||
"B": {"color": "Red"},
|
||||
"C": {"color": "Red"},
|
||||
"D": {"color": "Red"},
|
||||
"E": {"color": "Blue"},
|
||||
"F": {"color": "Blue"},
|
||||
"G": {"color": "Blue"},
|
||||
"H": {"color": "Blue"},
|
||||
"I": {"color": "Yellow"},
|
||||
"J": {"color": "Yellow"},
|
||||
"K": {"color": "Yellow"},
|
||||
"L": {"color": "Yellow"},
|
||||
}
|
||||
edges = [
|
||||
("A", "B"),
|
||||
@@ -316,12 +316,12 @@ class TestSNAPNoEdgeTypes(AbstractSNAP):
|
||||
|
||||
def build_summary_graph(self):
|
||||
nodes = {
|
||||
"Supernode-0": dict(color="Red"),
|
||||
"Supernode-1": dict(color="Red"),
|
||||
"Supernode-2": dict(color="Blue"),
|
||||
"Supernode-3": dict(color="Blue"),
|
||||
"Supernode-4": dict(color="Yellow"),
|
||||
"Supernode-5": dict(color="Yellow"),
|
||||
"Supernode-0": {"color": "Red"},
|
||||
"Supernode-1": {"color": "Red"},
|
||||
"Supernode-2": {"color": "Blue"},
|
||||
"Supernode-3": {"color": "Blue"},
|
||||
"Supernode-4": {"color": "Yellow"},
|
||||
"Supernode-5": {"color": "Yellow"},
|
||||
}
|
||||
edges = [
|
||||
("Supernode-0", "Supernode-0"),
|
||||
@@ -355,18 +355,18 @@ class TestSNAPNoEdgeTypes(AbstractSNAP):
|
||||
class TestSNAPUndirected(AbstractSNAP):
|
||||
def build_original_graph(self):
|
||||
nodes = {
|
||||
"A": dict(color="Red"),
|
||||
"B": dict(color="Red"),
|
||||
"C": dict(color="Red"),
|
||||
"D": dict(color="Red"),
|
||||
"E": dict(color="Blue"),
|
||||
"F": dict(color="Blue"),
|
||||
"G": dict(color="Blue"),
|
||||
"H": dict(color="Blue"),
|
||||
"I": dict(color="Yellow"),
|
||||
"J": dict(color="Yellow"),
|
||||
"K": dict(color="Yellow"),
|
||||
"L": dict(color="Yellow"),
|
||||
"A": {"color": "Red"},
|
||||
"B": {"color": "Red"},
|
||||
"C": {"color": "Red"},
|
||||
"D": {"color": "Red"},
|
||||
"E": {"color": "Blue"},
|
||||
"F": {"color": "Blue"},
|
||||
"G": {"color": "Blue"},
|
||||
"H": {"color": "Blue"},
|
||||
"I": {"color": "Yellow"},
|
||||
"J": {"color": "Yellow"},
|
||||
"K": {"color": "Yellow"},
|
||||
"L": {"color": "Yellow"},
|
||||
}
|
||||
edges = [
|
||||
("A", "B", "Strong"),
|
||||
@@ -394,12 +394,12 @@ class TestSNAPUndirected(AbstractSNAP):
|
||||
|
||||
def build_summary_graph(self):
|
||||
nodes = {
|
||||
"Supernode-0": dict(color="Red"),
|
||||
"Supernode-1": dict(color="Red"),
|
||||
"Supernode-2": dict(color="Blue"),
|
||||
"Supernode-3": dict(color="Blue"),
|
||||
"Supernode-4": dict(color="Yellow"),
|
||||
"Supernode-5": dict(color="Yellow"),
|
||||
"Supernode-0": {"color": "Red"},
|
||||
"Supernode-1": {"color": "Red"},
|
||||
"Supernode-2": {"color": "Blue"},
|
||||
"Supernode-3": {"color": "Blue"},
|
||||
"Supernode-4": {"color": "Yellow"},
|
||||
"Supernode-5": {"color": "Yellow"},
|
||||
}
|
||||
edges = [
|
||||
("Supernode-0", "Supernode-0", "Strong"),
|
||||
@@ -416,7 +416,7 @@ class TestSNAPUndirected(AbstractSNAP):
|
||||
G.add_node(node, **attributes)
|
||||
|
||||
for source, target, type in edges:
|
||||
G.add_edge(source, target, types=[dict(type=type)])
|
||||
G.add_edge(source, target, types=[{"type": type}])
|
||||
|
||||
supernodes = {
|
||||
"Supernode-0": {"A", "B"},
|
||||
@@ -433,14 +433,14 @@ class TestSNAPUndirected(AbstractSNAP):
|
||||
class TestSNAPDirected(AbstractSNAP):
|
||||
def build_original_graph(self):
|
||||
nodes = {
|
||||
"A": dict(color="Red"),
|
||||
"B": dict(color="Red"),
|
||||
"C": dict(color="Green"),
|
||||
"D": dict(color="Green"),
|
||||
"E": dict(color="Blue"),
|
||||
"F": dict(color="Blue"),
|
||||
"G": dict(color="Yellow"),
|
||||
"H": dict(color="Yellow"),
|
||||
"A": {"color": "Red"},
|
||||
"B": {"color": "Red"},
|
||||
"C": {"color": "Green"},
|
||||
"D": {"color": "Green"},
|
||||
"E": {"color": "Blue"},
|
||||
"F": {"color": "Blue"},
|
||||
"G": {"color": "Yellow"},
|
||||
"H": {"color": "Yellow"},
|
||||
}
|
||||
edges = [
|
||||
("A", "C", "Strong"),
|
||||
@@ -468,10 +468,10 @@ class TestSNAPDirected(AbstractSNAP):
|
||||
|
||||
def build_summary_graph(self):
|
||||
nodes = {
|
||||
"Supernode-0": dict(color="Red"),
|
||||
"Supernode-1": dict(color="Green"),
|
||||
"Supernode-2": dict(color="Blue"),
|
||||
"Supernode-3": dict(color="Yellow"),
|
||||
"Supernode-0": {"color": "Red"},
|
||||
"Supernode-1": {"color": "Green"},
|
||||
"Supernode-2": {"color": "Blue"},
|
||||
"Supernode-3": {"color": "Yellow"},
|
||||
}
|
||||
edges = [
|
||||
("Supernode-0", "Supernode-1", [{"type": "Strong"}]),
|
||||
@@ -503,15 +503,15 @@ class TestSNAPDirected(AbstractSNAP):
|
||||
class TestSNAPUndirectedMulti(AbstractSNAP):
|
||||
def build_original_graph(self):
|
||||
nodes = {
|
||||
"A": dict(color="Red"),
|
||||
"B": dict(color="Red"),
|
||||
"C": dict(color="Red"),
|
||||
"D": dict(color="Blue"),
|
||||
"E": dict(color="Blue"),
|
||||
"F": dict(color="Blue"),
|
||||
"G": dict(color="Yellow"),
|
||||
"H": dict(color="Yellow"),
|
||||
"I": dict(color="Yellow"),
|
||||
"A": {"color": "Red"},
|
||||
"B": {"color": "Red"},
|
||||
"C": {"color": "Red"},
|
||||
"D": {"color": "Blue"},
|
||||
"E": {"color": "Blue"},
|
||||
"F": {"color": "Blue"},
|
||||
"G": {"color": "Yellow"},
|
||||
"H": {"color": "Yellow"},
|
||||
"I": {"color": "Yellow"},
|
||||
}
|
||||
edges = [
|
||||
("A", "D", ["Weak", "Strong"]),
|
||||
@@ -536,12 +536,12 @@ class TestSNAPUndirectedMulti(AbstractSNAP):
|
||||
|
||||
def build_summary_graph(self):
|
||||
nodes = {
|
||||
"Supernode-0": dict(color="Red"),
|
||||
"Supernode-1": dict(color="Blue"),
|
||||
"Supernode-2": dict(color="Yellow"),
|
||||
"Supernode-3": dict(color="Blue"),
|
||||
"Supernode-4": dict(color="Yellow"),
|
||||
"Supernode-5": dict(color="Red"),
|
||||
"Supernode-0": {"color": "Red"},
|
||||
"Supernode-1": {"color": "Blue"},
|
||||
"Supernode-2": {"color": "Yellow"},
|
||||
"Supernode-3": {"color": "Blue"},
|
||||
"Supernode-4": {"color": "Yellow"},
|
||||
"Supernode-5": {"color": "Red"},
|
||||
}
|
||||
edges = [
|
||||
("Supernode-1", "Supernode-2", [{"type": "Weak"}]),
|
||||
@@ -574,14 +574,14 @@ class TestSNAPUndirectedMulti(AbstractSNAP):
|
||||
class TestSNAPDirectedMulti(AbstractSNAP):
|
||||
def build_original_graph(self):
|
||||
nodes = {
|
||||
"A": dict(color="Red"),
|
||||
"B": dict(color="Red"),
|
||||
"C": dict(color="Green"),
|
||||
"D": dict(color="Green"),
|
||||
"E": dict(color="Blue"),
|
||||
"F": dict(color="Blue"),
|
||||
"G": dict(color="Yellow"),
|
||||
"H": dict(color="Yellow"),
|
||||
"A": {"color": "Red"},
|
||||
"B": {"color": "Red"},
|
||||
"C": {"color": "Green"},
|
||||
"D": {"color": "Green"},
|
||||
"E": {"color": "Blue"},
|
||||
"F": {"color": "Blue"},
|
||||
"G": {"color": "Yellow"},
|
||||
"H": {"color": "Yellow"},
|
||||
}
|
||||
edges = [
|
||||
("A", "C", ["Weak", "Strong"]),
|
||||
@@ -610,10 +610,10 @@ class TestSNAPDirectedMulti(AbstractSNAP):
|
||||
|
||||
def build_summary_graph(self):
|
||||
nodes = {
|
||||
"Supernode-0": dict(color="Red"),
|
||||
"Supernode-1": dict(color="Blue"),
|
||||
"Supernode-2": dict(color="Yellow"),
|
||||
"Supernode-3": dict(color="Blue"),
|
||||
"Supernode-0": {"color": "Red"},
|
||||
"Supernode-1": {"color": "Blue"},
|
||||
"Supernode-2": {"color": "Yellow"},
|
||||
"Supernode-3": {"color": "Blue"},
|
||||
}
|
||||
edges = [
|
||||
("Supernode-0", "Supernode-1", ["Weak", "Strong"]),
|
||||
|
||||
@@ -16,11 +16,11 @@ class TestGeneratorThreshold:
|
||||
def test_threshold_sequence_graph_test(self):
|
||||
G = nx.star_graph(10)
|
||||
assert nxt.is_threshold_graph(G)
|
||||
assert nxt.is_threshold_sequence(list(d for n, d in G.degree()))
|
||||
assert nxt.is_threshold_sequence([d for n, d in G.degree()])
|
||||
|
||||
G = nx.complete_graph(10)
|
||||
assert nxt.is_threshold_graph(G)
|
||||
assert nxt.is_threshold_sequence(list(d for n, d in G.degree()))
|
||||
assert nxt.is_threshold_sequence([d for n, d in G.degree()])
|
||||
|
||||
deg = [3, 2, 2, 1, 1, 1]
|
||||
assert not nxt.is_threshold_sequence(deg)
|
||||
|
||||
@@ -56,8 +56,8 @@ def test_all_triplets():
|
||||
for k in range(j + 1, 7)
|
||||
]
|
||||
expected = [set(x.split(",")) for x in expected]
|
||||
actual = list(set(x) for x in nx.all_triplets(G))
|
||||
assert all([any([s1 == s2 for s1 in expected]) for s2 in actual])
|
||||
actual = [set(x) for x in nx.all_triplets(G)]
|
||||
assert all(any(s1 == s2 for s1 in expected) for s2 in actual)
|
||||
|
||||
|
||||
def test_all_triads():
|
||||
@@ -72,7 +72,7 @@ def test_all_triads():
|
||||
]
|
||||
expected = [G.subgraph(x.split(",")) for x in expected]
|
||||
actual = list(nx.all_triads(G))
|
||||
assert all(any([nx.is_isomorphic(G1, G2) for G1 in expected]) for G2 in actual)
|
||||
assert all(any(nx.is_isomorphic(G1, G2) for G1 in expected) for G2 in actual)
|
||||
|
||||
|
||||
def test_triad_type():
|
||||
|
||||
Reference in New Issue
Block a user