Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,77 @@
|
|||
from itertools import groupby
|
||||
|
||||
import pytest
|
||||
|
||||
import networkx as nx
|
||||
from networkx.testing import assert_edges_equal, assert_nodes_equal
|
||||
from networkx import graph_atlas
|
||||
from networkx import graph_atlas_g
|
||||
from networkx.generators.atlas import NUM_GRAPHS
|
||||
from networkx.utils import pairwise
|
||||
|
||||
|
||||
class TestAtlasGraph:
|
||||
"""Unit tests for the :func:`~networkx.graph_atlas` function."""
|
||||
|
||||
def test_index_too_small(self):
|
||||
with pytest.raises(ValueError):
|
||||
graph_atlas(-1)
|
||||
|
||||
def test_index_too_large(self):
|
||||
with pytest.raises(ValueError):
|
||||
graph_atlas(NUM_GRAPHS)
|
||||
|
||||
def test_graph(self):
|
||||
G = graph_atlas(6)
|
||||
assert_nodes_equal(G.nodes(), range(3))
|
||||
assert_edges_equal(G.edges(), [(0, 1), (0, 2)])
|
||||
|
||||
|
||||
class TestAtlasGraphG:
|
||||
"""Unit tests for the :func:`~networkx.graph_atlas_g` function."""
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
cls.GAG = graph_atlas_g()
|
||||
|
||||
def test_sizes(self):
|
||||
G = self.GAG[0]
|
||||
assert G.number_of_nodes() == 0
|
||||
assert G.number_of_edges() == 0
|
||||
|
||||
G = self.GAG[7]
|
||||
assert G.number_of_nodes() == 3
|
||||
assert G.number_of_edges() == 3
|
||||
|
||||
def test_names(self):
|
||||
for i, G in enumerate(self.GAG):
|
||||
assert int(G.name[1:]) == i
|
||||
|
||||
def test_nondecreasing_nodes(self):
|
||||
# check for nondecreasing number of nodes
|
||||
for n1, n2 in pairwise(map(len, self.GAG)):
|
||||
assert n2 <= n1 + 1
|
||||
|
||||
def test_nondecreasing_edges(self):
|
||||
# check for nondecreasing number of edges (for fixed number of
|
||||
# nodes)
|
||||
for n, group in groupby(self.GAG, key=nx.number_of_nodes):
|
||||
for m1, m2 in pairwise(map(nx.number_of_edges, group)):
|
||||
assert m2 <= m1 + 1
|
||||
|
||||
def test_nondecreasing_degree_sequence(self):
|
||||
# Check for lexicographically nondecreasing degree sequences
|
||||
# (for fixed number of nodes and edges).
|
||||
#
|
||||
# There are three exceptions to this rule in the order given in
|
||||
# the "Atlas of Graphs" book, so we need to manually exclude
|
||||
# those.
|
||||
exceptions = [("G55", "G56"), ("G1007", "G1008"), ("G1012", "G1013")]
|
||||
for n, group in groupby(self.GAG, key=nx.number_of_nodes):
|
||||
for m, group in groupby(group, key=nx.number_of_edges):
|
||||
for G1, G2 in pairwise(group):
|
||||
if (G1.name, G2.name) in exceptions:
|
||||
continue
|
||||
d1 = sorted(d for v, d in G1.degree())
|
||||
d2 = sorted(d for v, d in G2.degree())
|
||||
assert d1 <= d2
|
467
venv/Lib/site-packages/networkx/generators/tests/test_classic.py
Normal file
467
venv/Lib/site-packages/networkx/generators/tests/test_classic.py
Normal file
|
@ -0,0 +1,467 @@
|
|||
"""
|
||||
====================
|
||||
Generators - Classic
|
||||
====================
|
||||
|
||||
Unit tests for various classic graph generators in generators/classic.py
|
||||
"""
|
||||
import itertools
|
||||
|
||||
import pytest
|
||||
import networkx as nx
|
||||
from networkx.algorithms.isomorphism.isomorph import graph_could_be_isomorphic
|
||||
from networkx.testing import assert_edges_equal
|
||||
from networkx.testing import assert_nodes_equal
|
||||
|
||||
is_isomorphic = graph_could_be_isomorphic
|
||||
|
||||
|
||||
class TestGeneratorClassic:
|
||||
def test_balanced_tree(self):
|
||||
# balanced_tree(r,h) is a tree with (r**(h+1)-1)/(r-1) edges
|
||||
for r, h in [(2, 2), (3, 3), (6, 2)]:
|
||||
t = nx.balanced_tree(r, h)
|
||||
order = t.order()
|
||||
assert order == (r ** (h + 1) - 1) / (r - 1)
|
||||
assert nx.is_connected(t)
|
||||
assert t.size() == order - 1
|
||||
dh = nx.degree_histogram(t)
|
||||
assert dh[0] == 0 # no nodes of 0
|
||||
assert dh[1] == r ** h # nodes of degree 1 are leaves
|
||||
assert dh[r] == 1 # root is degree r
|
||||
assert dh[r + 1] == order - r ** h - 1 # everyone else is degree r+1
|
||||
assert len(dh) == r + 2
|
||||
|
||||
def test_balanced_tree_star(self):
|
||||
# balanced_tree(r,1) is the r-star
|
||||
t = nx.balanced_tree(r=2, h=1)
|
||||
assert is_isomorphic(t, nx.star_graph(2))
|
||||
t = nx.balanced_tree(r=5, h=1)
|
||||
assert is_isomorphic(t, nx.star_graph(5))
|
||||
t = nx.balanced_tree(r=10, h=1)
|
||||
assert is_isomorphic(t, nx.star_graph(10))
|
||||
|
||||
def test_balanced_tree_path(self):
|
||||
"""Tests that the balanced tree with branching factor one is the
|
||||
path graph.
|
||||
|
||||
"""
|
||||
# A tree of height four has five levels.
|
||||
T = nx.balanced_tree(1, 4)
|
||||
P = nx.path_graph(5)
|
||||
assert is_isomorphic(T, P)
|
||||
|
||||
def test_full_rary_tree(self):
|
||||
r = 2
|
||||
n = 9
|
||||
t = nx.full_rary_tree(r, n)
|
||||
assert t.order() == n
|
||||
assert nx.is_connected(t)
|
||||
dh = nx.degree_histogram(t)
|
||||
assert dh[0] == 0 # no nodes of 0
|
||||
assert dh[1] == 5 # nodes of degree 1 are leaves
|
||||
assert dh[r] == 1 # root is degree r
|
||||
assert dh[r + 1] == 9 - 5 - 1 # everyone else is degree r+1
|
||||
assert len(dh) == r + 2
|
||||
|
||||
def test_full_rary_tree_balanced(self):
|
||||
t = nx.full_rary_tree(2, 15)
|
||||
th = nx.balanced_tree(2, 3)
|
||||
assert is_isomorphic(t, th)
|
||||
|
||||
def test_full_rary_tree_path(self):
|
||||
t = nx.full_rary_tree(1, 10)
|
||||
assert is_isomorphic(t, nx.path_graph(10))
|
||||
|
||||
def test_full_rary_tree_empty(self):
|
||||
t = nx.full_rary_tree(0, 10)
|
||||
assert is_isomorphic(t, nx.empty_graph(10))
|
||||
t = nx.full_rary_tree(3, 0)
|
||||
assert is_isomorphic(t, nx.empty_graph(0))
|
||||
|
||||
def test_full_rary_tree_3_20(self):
|
||||
t = nx.full_rary_tree(3, 20)
|
||||
assert t.order() == 20
|
||||
|
||||
def test_barbell_graph(self):
|
||||
# number of nodes = 2*m1 + m2 (2 m1-complete graphs + m2-path + 2 edges)
|
||||
# number of edges = 2*(nx.number_of_edges(m1-complete graph) + m2 + 1
|
||||
m1 = 3
|
||||
m2 = 5
|
||||
b = nx.barbell_graph(m1, m2)
|
||||
assert nx.number_of_nodes(b) == 2 * m1 + m2
|
||||
assert nx.number_of_edges(b) == m1 * (m1 - 1) + m2 + 1
|
||||
|
||||
m1 = 4
|
||||
m2 = 10
|
||||
b = nx.barbell_graph(m1, m2)
|
||||
assert nx.number_of_nodes(b) == 2 * m1 + m2
|
||||
assert nx.number_of_edges(b) == m1 * (m1 - 1) + m2 + 1
|
||||
|
||||
m1 = 3
|
||||
m2 = 20
|
||||
b = nx.barbell_graph(m1, m2)
|
||||
assert nx.number_of_nodes(b) == 2 * m1 + m2
|
||||
assert nx.number_of_edges(b) == m1 * (m1 - 1) + m2 + 1
|
||||
|
||||
# Raise NetworkXError if m1<2
|
||||
m1 = 1
|
||||
m2 = 20
|
||||
pytest.raises(nx.NetworkXError, nx.barbell_graph, m1, m2)
|
||||
|
||||
# Raise NetworkXError if m2<0
|
||||
m1 = 5
|
||||
m2 = -2
|
||||
pytest.raises(nx.NetworkXError, nx.barbell_graph, m1, m2)
|
||||
|
||||
# nx.barbell_graph(2,m) = nx.path_graph(m+4)
|
||||
m1 = 2
|
||||
m2 = 5
|
||||
b = nx.barbell_graph(m1, m2)
|
||||
assert is_isomorphic(b, nx.path_graph(m2 + 4))
|
||||
|
||||
m1 = 2
|
||||
m2 = 10
|
||||
b = nx.barbell_graph(m1, m2)
|
||||
assert is_isomorphic(b, nx.path_graph(m2 + 4))
|
||||
|
||||
m1 = 2
|
||||
m2 = 20
|
||||
b = nx.barbell_graph(m1, m2)
|
||||
assert is_isomorphic(b, nx.path_graph(m2 + 4))
|
||||
|
||||
pytest.raises(
|
||||
nx.NetworkXError, nx.barbell_graph, m1, m2, create_using=nx.DiGraph()
|
||||
)
|
||||
|
||||
mb = nx.barbell_graph(m1, m2, create_using=nx.MultiGraph())
|
||||
assert_edges_equal(mb.edges(), b.edges())
|
||||
|
||||
def test_binomial_tree(self):
|
||||
for n in range(0, 4):
|
||||
b = nx.binomial_tree(n)
|
||||
assert nx.number_of_nodes(b) == 2 ** n
|
||||
assert nx.number_of_edges(b) == (2 ** n - 1)
|
||||
|
||||
def test_complete_graph(self):
|
||||
# complete_graph(m) is a connected graph with
|
||||
# m nodes and m*(m+1)/2 edges
|
||||
for m in [0, 1, 3, 5]:
|
||||
g = nx.complete_graph(m)
|
||||
assert nx.number_of_nodes(g) == m
|
||||
assert nx.number_of_edges(g) == m * (m - 1) // 2
|
||||
|
||||
mg = nx.complete_graph(m, create_using=nx.MultiGraph)
|
||||
assert_edges_equal(mg.edges(), g.edges())
|
||||
|
||||
g = nx.complete_graph("abc")
|
||||
assert_nodes_equal(g.nodes(), ["a", "b", "c"])
|
||||
assert g.size() == 3
|
||||
|
||||
def test_complete_digraph(self):
|
||||
# complete_graph(m) is a connected graph with
|
||||
# m nodes and m*(m+1)/2 edges
|
||||
for m in [0, 1, 3, 5]:
|
||||
g = nx.complete_graph(m, create_using=nx.DiGraph)
|
||||
assert nx.number_of_nodes(g) == m
|
||||
assert nx.number_of_edges(g) == m * (m - 1)
|
||||
|
||||
g = nx.complete_graph("abc", create_using=nx.DiGraph)
|
||||
assert len(g) == 3
|
||||
assert g.size() == 6
|
||||
assert g.is_directed()
|
||||
|
||||
def test_circular_ladder_graph(self):
|
||||
G = nx.circular_ladder_graph(5)
|
||||
pytest.raises(
|
||||
nx.NetworkXError, nx.circular_ladder_graph, 5, create_using=nx.DiGraph
|
||||
)
|
||||
mG = nx.circular_ladder_graph(5, create_using=nx.MultiGraph)
|
||||
assert_edges_equal(mG.edges(), G.edges())
|
||||
|
||||
def test_circulant_graph(self):
|
||||
# Ci_n(1) is the cycle graph for all n
|
||||
Ci6_1 = nx.circulant_graph(6, [1])
|
||||
C6 = nx.cycle_graph(6)
|
||||
assert_edges_equal(Ci6_1.edges(), C6.edges())
|
||||
|
||||
# Ci_n(1, 2, ..., n div 2) is the complete graph for all n
|
||||
Ci7 = nx.circulant_graph(7, [1, 2, 3])
|
||||
K7 = nx.complete_graph(7)
|
||||
assert_edges_equal(Ci7.edges(), K7.edges())
|
||||
|
||||
# Ci_6(1, 3) is K_3,3 i.e. the utility graph
|
||||
Ci6_1_3 = nx.circulant_graph(6, [1, 3])
|
||||
K3_3 = nx.complete_bipartite_graph(3, 3)
|
||||
assert is_isomorphic(Ci6_1_3, K3_3)
|
||||
|
||||
def test_cycle_graph(self):
|
||||
G = nx.cycle_graph(4)
|
||||
assert_edges_equal(G.edges(), [(0, 1), (0, 3), (1, 2), (2, 3)])
|
||||
mG = nx.cycle_graph(4, create_using=nx.MultiGraph)
|
||||
assert_edges_equal(mG.edges(), [(0, 1), (0, 3), (1, 2), (2, 3)])
|
||||
G = nx.cycle_graph(4, create_using=nx.DiGraph)
|
||||
assert not G.has_edge(2, 1)
|
||||
assert G.has_edge(1, 2)
|
||||
assert G.is_directed()
|
||||
|
||||
G = nx.cycle_graph("abc")
|
||||
assert len(G) == 3
|
||||
assert G.size() == 3
|
||||
g = nx.cycle_graph("abc", nx.DiGraph)
|
||||
assert len(g) == 3
|
||||
assert g.size() == 3
|
||||
assert g.is_directed()
|
||||
|
||||
def test_dorogovtsev_goltsev_mendes_graph(self):
|
||||
G = nx.dorogovtsev_goltsev_mendes_graph(0)
|
||||
assert_edges_equal(G.edges(), [(0, 1)])
|
||||
assert_nodes_equal(list(G), [0, 1])
|
||||
G = nx.dorogovtsev_goltsev_mendes_graph(1)
|
||||
assert_edges_equal(G.edges(), [(0, 1), (0, 2), (1, 2)])
|
||||
assert nx.average_clustering(G) == 1.0
|
||||
assert sorted(nx.triangles(G).values()) == [1, 1, 1]
|
||||
G = nx.dorogovtsev_goltsev_mendes_graph(10)
|
||||
assert nx.number_of_nodes(G) == 29526
|
||||
assert nx.number_of_edges(G) == 59049
|
||||
assert G.degree(0) == 1024
|
||||
assert G.degree(1) == 1024
|
||||
assert G.degree(2) == 1024
|
||||
|
||||
pytest.raises(
|
||||
nx.NetworkXError,
|
||||
nx.dorogovtsev_goltsev_mendes_graph,
|
||||
7,
|
||||
create_using=nx.DiGraph,
|
||||
)
|
||||
pytest.raises(
|
||||
nx.NetworkXError,
|
||||
nx.dorogovtsev_goltsev_mendes_graph,
|
||||
7,
|
||||
create_using=nx.MultiGraph,
|
||||
)
|
||||
|
||||
def test_create_using(self):
|
||||
G = nx.empty_graph()
|
||||
assert isinstance(G, nx.Graph)
|
||||
pytest.raises(TypeError, nx.empty_graph, create_using=0.0)
|
||||
pytest.raises(TypeError, nx.empty_graph, create_using="Graph")
|
||||
|
||||
G = nx.empty_graph(create_using=nx.MultiGraph)
|
||||
assert isinstance(G, nx.MultiGraph)
|
||||
G = nx.empty_graph(create_using=nx.DiGraph)
|
||||
assert isinstance(G, nx.DiGraph)
|
||||
|
||||
G = nx.empty_graph(create_using=nx.DiGraph, default=nx.MultiGraph)
|
||||
assert isinstance(G, nx.DiGraph)
|
||||
G = nx.empty_graph(create_using=None, default=nx.MultiGraph)
|
||||
assert isinstance(G, nx.MultiGraph)
|
||||
G = nx.empty_graph(default=nx.MultiGraph)
|
||||
assert isinstance(G, nx.MultiGraph)
|
||||
|
||||
G = nx.path_graph(5)
|
||||
H = nx.empty_graph(create_using=G)
|
||||
assert not H.is_multigraph()
|
||||
assert not H.is_directed()
|
||||
assert len(H) == 0
|
||||
assert G is H
|
||||
|
||||
H = nx.empty_graph(create_using=nx.MultiGraph())
|
||||
assert H.is_multigraph()
|
||||
assert not H.is_directed()
|
||||
assert G is not H
|
||||
|
||||
def test_empty_graph(self):
|
||||
G = nx.empty_graph()
|
||||
assert nx.number_of_nodes(G) == 0
|
||||
G = nx.empty_graph(42)
|
||||
assert nx.number_of_nodes(G) == 42
|
||||
assert nx.number_of_edges(G) == 0
|
||||
|
||||
G = nx.empty_graph("abc")
|
||||
assert len(G) == 3
|
||||
assert G.size() == 0
|
||||
|
||||
# create empty digraph
|
||||
G = nx.empty_graph(42, create_using=nx.DiGraph(name="duh"))
|
||||
assert nx.number_of_nodes(G) == 42
|
||||
assert nx.number_of_edges(G) == 0
|
||||
assert isinstance(G, nx.DiGraph)
|
||||
|
||||
# create empty multigraph
|
||||
G = nx.empty_graph(42, create_using=nx.MultiGraph(name="duh"))
|
||||
assert nx.number_of_nodes(G) == 42
|
||||
assert nx.number_of_edges(G) == 0
|
||||
assert isinstance(G, nx.MultiGraph)
|
||||
|
||||
# create empty graph from another
|
||||
pete = nx.petersen_graph()
|
||||
G = nx.empty_graph(42, create_using=pete)
|
||||
assert nx.number_of_nodes(G) == 42
|
||||
assert nx.number_of_edges(G) == 0
|
||||
assert isinstance(G, nx.Graph)
|
||||
|
||||
def test_ladder_graph(self):
|
||||
for i, G in [
|
||||
(0, nx.empty_graph(0)),
|
||||
(1, nx.path_graph(2)),
|
||||
(2, nx.hypercube_graph(2)),
|
||||
(10, nx.grid_graph([2, 10])),
|
||||
]:
|
||||
assert is_isomorphic(nx.ladder_graph(i), G)
|
||||
|
||||
pytest.raises(nx.NetworkXError, nx.ladder_graph, 2, create_using=nx.DiGraph)
|
||||
|
||||
g = nx.ladder_graph(2)
|
||||
mg = nx.ladder_graph(2, create_using=nx.MultiGraph)
|
||||
assert_edges_equal(mg.edges(), g.edges())
|
||||
|
||||
def test_lollipop_graph(self):
|
||||
# number of nodes = m1 + m2
|
||||
# number of edges = nx.number_of_edges(nx.complete_graph(m1)) + m2
|
||||
for m1, m2 in [(3, 5), (4, 10), (3, 20)]:
|
||||
b = nx.lollipop_graph(m1, m2)
|
||||
assert nx.number_of_nodes(b) == m1 + m2
|
||||
assert nx.number_of_edges(b) == m1 * (m1 - 1) / 2 + m2
|
||||
|
||||
# Raise NetworkXError if m<2
|
||||
pytest.raises(nx.NetworkXError, nx.lollipop_graph, 1, 20)
|
||||
|
||||
# Raise NetworkXError if n<0
|
||||
pytest.raises(nx.NetworkXError, nx.lollipop_graph, 5, -2)
|
||||
|
||||
# lollipop_graph(2,m) = path_graph(m+2)
|
||||
for m1, m2 in [(2, 5), (2, 10), (2, 20)]:
|
||||
b = nx.lollipop_graph(m1, m2)
|
||||
assert is_isomorphic(b, nx.path_graph(m2 + 2))
|
||||
|
||||
pytest.raises(
|
||||
nx.NetworkXError, nx.lollipop_graph, m1, m2, create_using=nx.DiGraph
|
||||
)
|
||||
|
||||
mb = nx.lollipop_graph(m1, m2, create_using=nx.MultiGraph)
|
||||
assert_edges_equal(mb.edges(), b.edges())
|
||||
|
||||
g = nx.lollipop_graph([1, 2, 3, 4], "abc")
|
||||
assert len(g) == 7
|
||||
assert g.size() == 9
|
||||
|
||||
def test_null_graph(self):
|
||||
assert nx.number_of_nodes(nx.null_graph()) == 0
|
||||
|
||||
def test_path_graph(self):
|
||||
p = nx.path_graph(0)
|
||||
assert is_isomorphic(p, nx.null_graph())
|
||||
|
||||
p = nx.path_graph(1)
|
||||
assert is_isomorphic(p, nx.empty_graph(1))
|
||||
|
||||
p = nx.path_graph(10)
|
||||
assert nx.is_connected(p)
|
||||
assert sorted(d for n, d in p.degree()) == [1, 1, 2, 2, 2, 2, 2, 2, 2, 2]
|
||||
assert p.order() - 1 == p.size()
|
||||
|
||||
dp = nx.path_graph(3, create_using=nx.DiGraph)
|
||||
assert dp.has_edge(0, 1)
|
||||
assert not dp.has_edge(1, 0)
|
||||
|
||||
mp = nx.path_graph(10, create_using=nx.MultiGraph)
|
||||
assert_edges_equal(mp.edges(), p.edges())
|
||||
|
||||
G = nx.path_graph("abc")
|
||||
assert len(G) == 3
|
||||
assert G.size() == 2
|
||||
g = nx.path_graph("abc", nx.DiGraph)
|
||||
assert len(g) == 3
|
||||
assert g.size() == 2
|
||||
assert g.is_directed()
|
||||
|
||||
def test_star_graph(self):
|
||||
star_graph = nx.star_graph
|
||||
assert is_isomorphic(star_graph(0), nx.empty_graph(1))
|
||||
assert is_isomorphic(star_graph(1), nx.path_graph(2))
|
||||
assert is_isomorphic(star_graph(2), nx.path_graph(3))
|
||||
assert is_isomorphic(star_graph(5), nx.complete_bipartite_graph(1, 5))
|
||||
|
||||
s = star_graph(10)
|
||||
assert sorted(d for n, d in s.degree()) == [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10]
|
||||
|
||||
pytest.raises(nx.NetworkXError, star_graph, 10, create_using=nx.DiGraph)
|
||||
|
||||
ms = star_graph(10, create_using=nx.MultiGraph)
|
||||
assert_edges_equal(ms.edges(), s.edges())
|
||||
|
||||
G = star_graph("abcdefg")
|
||||
assert len(G) == 7
|
||||
assert G.size() == 6
|
||||
|
||||
def test_trivial_graph(self):
|
||||
assert nx.number_of_nodes(nx.trivial_graph()) == 1
|
||||
|
||||
def test_turan_graph(self):
|
||||
assert nx.number_of_edges(nx.turan_graph(13, 4)) == 63
|
||||
assert is_isomorphic(
|
||||
nx.turan_graph(13, 4), nx.complete_multipartite_graph(3, 4, 3, 3)
|
||||
)
|
||||
|
||||
def test_wheel_graph(self):
|
||||
for n, G in [
|
||||
(0, nx.null_graph()),
|
||||
(1, nx.empty_graph(1)),
|
||||
(2, nx.path_graph(2)),
|
||||
(3, nx.complete_graph(3)),
|
||||
(4, nx.complete_graph(4)),
|
||||
]:
|
||||
g = nx.wheel_graph(n)
|
||||
assert is_isomorphic(g, G)
|
||||
|
||||
g = nx.wheel_graph(10)
|
||||
assert sorted(d for n, d in g.degree()) == [3, 3, 3, 3, 3, 3, 3, 3, 3, 9]
|
||||
|
||||
pytest.raises(nx.NetworkXError, nx.wheel_graph, 10, create_using=nx.DiGraph)
|
||||
|
||||
mg = nx.wheel_graph(10, create_using=nx.MultiGraph())
|
||||
assert_edges_equal(mg.edges(), g.edges())
|
||||
|
||||
G = nx.wheel_graph("abc")
|
||||
assert len(G) == 3
|
||||
assert G.size() == 3
|
||||
|
||||
def test_complete_0_partite_graph(self):
|
||||
"""Tests that the complete 0-partite graph is the null graph."""
|
||||
G = nx.complete_multipartite_graph()
|
||||
H = nx.null_graph()
|
||||
assert_nodes_equal(G, H)
|
||||
assert_edges_equal(G.edges(), H.edges())
|
||||
|
||||
def test_complete_1_partite_graph(self):
|
||||
"""Tests that the complete 1-partite graph is the empty graph."""
|
||||
G = nx.complete_multipartite_graph(3)
|
||||
H = nx.empty_graph(3)
|
||||
assert_nodes_equal(G, H)
|
||||
assert_edges_equal(G.edges(), H.edges())
|
||||
|
||||
def test_complete_2_partite_graph(self):
|
||||
"""Tests that the complete 2-partite graph is the complete bipartite
|
||||
graph.
|
||||
|
||||
"""
|
||||
G = nx.complete_multipartite_graph(2, 3)
|
||||
H = nx.complete_bipartite_graph(2, 3)
|
||||
assert_nodes_equal(G, H)
|
||||
assert_edges_equal(G.edges(), H.edges())
|
||||
|
||||
def test_complete_multipartite_graph(self):
|
||||
"""Tests for generating the complete multipartite graph."""
|
||||
G = nx.complete_multipartite_graph(2, 3, 4)
|
||||
blocks = [(0, 1), (2, 3, 4), (5, 6, 7, 8)]
|
||||
# Within each block, no two vertices should be adjacent.
|
||||
for block in blocks:
|
||||
for u, v in itertools.combinations_with_replacement(block, 2):
|
||||
assert v not in G[u]
|
||||
assert G.nodes[u] == G.nodes[v]
|
||||
# Across blocks, all vertices should be adjacent.
|
||||
for (block1, block2) in itertools.combinations(blocks, 2):
|
||||
for u, v in itertools.product(block1, block2):
|
||||
assert v in G[u]
|
||||
assert G.nodes[u] != G.nodes[v]
|
|
@ -0,0 +1,20 @@
|
|||
"""Unit tests for the :mod:`networkx.generators.cographs` module.
|
||||
|
||||
"""
|
||||
|
||||
import networkx as nx
|
||||
|
||||
|
||||
def test_random_cograph():
|
||||
n = 3
|
||||
G = nx.random_cograph(n)
|
||||
|
||||
assert len(G) == 2 ** n
|
||||
|
||||
# Every connected subgraph of G has diameter <= 2
|
||||
if nx.is_connected(G):
|
||||
assert nx.diameter(G) <= 2
|
||||
else:
|
||||
components = nx.connected_components(G)
|
||||
for component in components:
|
||||
assert nx.diameter(G.subgraph(component)) <= 2
|
|
@ -0,0 +1,267 @@
|
|||
import networkx as nx
|
||||
import pytest
|
||||
|
||||
|
||||
def test_random_partition_graph():
|
||||
G = nx.random_partition_graph([3, 3, 3], 1, 0, seed=42)
|
||||
C = G.graph["partition"]
|
||||
assert C == [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}]
|
||||
assert len(G) == 9
|
||||
assert len(list(G.edges())) == 9
|
||||
|
||||
G = nx.random_partition_graph([3, 3, 3], 0, 1)
|
||||
C = G.graph["partition"]
|
||||
assert C == [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}]
|
||||
assert len(G) == 9
|
||||
assert len(list(G.edges())) == 27
|
||||
|
||||
G = nx.random_partition_graph([3, 3, 3], 1, 0, directed=True)
|
||||
C = G.graph["partition"]
|
||||
assert C == [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}]
|
||||
assert len(G) == 9
|
||||
assert len(list(G.edges())) == 18
|
||||
|
||||
G = nx.random_partition_graph([3, 3, 3], 0, 1, directed=True)
|
||||
C = G.graph["partition"]
|
||||
assert C == [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}]
|
||||
assert len(G) == 9
|
||||
assert len(list(G.edges())) == 54
|
||||
|
||||
G = nx.random_partition_graph([1, 2, 3, 4, 5], 0.5, 0.1)
|
||||
C = G.graph["partition"]
|
||||
assert C == [{0}, {1, 2}, {3, 4, 5}, {6, 7, 8, 9}, {10, 11, 12, 13, 14}]
|
||||
assert len(G) == 15
|
||||
|
||||
rpg = nx.random_partition_graph
|
||||
pytest.raises(nx.NetworkXError, rpg, [1, 2, 3], 1.1, 0.1)
|
||||
pytest.raises(nx.NetworkXError, rpg, [1, 2, 3], -0.1, 0.1)
|
||||
pytest.raises(nx.NetworkXError, rpg, [1, 2, 3], 0.1, 1.1)
|
||||
pytest.raises(nx.NetworkXError, rpg, [1, 2, 3], 0.1, -0.1)
|
||||
|
||||
|
||||
def test_planted_partition_graph():
|
||||
G = nx.planted_partition_graph(4, 3, 1, 0, seed=42)
|
||||
C = G.graph["partition"]
|
||||
assert len(C) == 4
|
||||
assert len(G) == 12
|
||||
assert len(list(G.edges())) == 12
|
||||
|
||||
G = nx.planted_partition_graph(4, 3, 0, 1)
|
||||
C = G.graph["partition"]
|
||||
assert len(C) == 4
|
||||
assert len(G) == 12
|
||||
assert len(list(G.edges())) == 54
|
||||
|
||||
G = nx.planted_partition_graph(10, 4, 0.5, 0.1, seed=42)
|
||||
C = G.graph["partition"]
|
||||
assert len(C) == 10
|
||||
assert len(G) == 40
|
||||
|
||||
G = nx.planted_partition_graph(4, 3, 1, 0, directed=True)
|
||||
C = G.graph["partition"]
|
||||
assert len(C) == 4
|
||||
assert len(G) == 12
|
||||
assert len(list(G.edges())) == 24
|
||||
|
||||
G = nx.planted_partition_graph(4, 3, 0, 1, directed=True)
|
||||
C = G.graph["partition"]
|
||||
assert len(C) == 4
|
||||
assert len(G) == 12
|
||||
assert len(list(G.edges())) == 108
|
||||
|
||||
G = nx.planted_partition_graph(10, 4, 0.5, 0.1, seed=42, directed=True)
|
||||
C = G.graph["partition"]
|
||||
assert len(C) == 10
|
||||
assert len(G) == 40
|
||||
|
||||
ppg = nx.planted_partition_graph
|
||||
pytest.raises(nx.NetworkXError, ppg, 3, 3, 1.1, 0.1)
|
||||
pytest.raises(nx.NetworkXError, ppg, 3, 3, -0.1, 0.1)
|
||||
pytest.raises(nx.NetworkXError, ppg, 3, 3, 0.1, 1.1)
|
||||
pytest.raises(nx.NetworkXError, ppg, 3, 3, 0.1, -0.1)
|
||||
|
||||
|
||||
def test_relaxed_caveman_graph():
|
||||
G = nx.relaxed_caveman_graph(4, 3, 0)
|
||||
assert len(G) == 12
|
||||
G = nx.relaxed_caveman_graph(4, 3, 1)
|
||||
assert len(G) == 12
|
||||
G = nx.relaxed_caveman_graph(4, 3, 0.5)
|
||||
assert len(G) == 12
|
||||
G = nx.relaxed_caveman_graph(4, 3, 0.5, seed=42)
|
||||
assert len(G) == 12
|
||||
|
||||
|
||||
def test_connected_caveman_graph():
|
||||
G = nx.connected_caveman_graph(4, 3)
|
||||
assert len(G) == 12
|
||||
|
||||
G = nx.connected_caveman_graph(1, 5)
|
||||
K5 = nx.complete_graph(5)
|
||||
K5.remove_edge(3, 4)
|
||||
assert nx.is_isomorphic(G, K5)
|
||||
|
||||
# need at least 2 nodes in each clique
|
||||
pytest.raises(nx.NetworkXError, nx.connected_caveman_graph, 4, 1)
|
||||
|
||||
|
||||
def test_caveman_graph():
|
||||
G = nx.caveman_graph(4, 3)
|
||||
assert len(G) == 12
|
||||
|
||||
G = nx.caveman_graph(1, 5)
|
||||
K5 = nx.complete_graph(5)
|
||||
assert nx.is_isomorphic(G, K5)
|
||||
|
||||
|
||||
def test_gaussian_random_partition_graph():
|
||||
G = nx.gaussian_random_partition_graph(100, 10, 10, 0.3, 0.01)
|
||||
assert len(G) == 100
|
||||
G = nx.gaussian_random_partition_graph(100, 10, 10, 0.3, 0.01, directed=True)
|
||||
assert len(G) == 100
|
||||
G = nx.gaussian_random_partition_graph(
|
||||
100, 10, 10, 0.3, 0.01, directed=False, seed=42
|
||||
)
|
||||
assert len(G) == 100
|
||||
assert not isinstance(G, nx.DiGraph)
|
||||
G = nx.gaussian_random_partition_graph(
|
||||
100, 10, 10, 0.3, 0.01, directed=True, seed=42
|
||||
)
|
||||
assert len(G) == 100
|
||||
assert isinstance(G, nx.DiGraph)
|
||||
pytest.raises(
|
||||
nx.NetworkXError, nx.gaussian_random_partition_graph, 100, 101, 10, 1, 0
|
||||
)
|
||||
|
||||
|
||||
def test_ring_of_cliques():
|
||||
for i in range(2, 20, 3):
|
||||
for j in range(2, 20, 3):
|
||||
G = nx.ring_of_cliques(i, j)
|
||||
assert G.number_of_nodes() == i * j
|
||||
if i != 2 or j != 1:
|
||||
expected_num_edges = i * (((j * (j - 1)) // 2) + 1)
|
||||
else:
|
||||
# the edge that already exists cannot be duplicated
|
||||
expected_num_edges = i * (((j * (j - 1)) // 2) + 1) - 1
|
||||
assert G.number_of_edges() == expected_num_edges
|
||||
pytest.raises(nx.NetworkXError, nx.ring_of_cliques, 1, 5)
|
||||
pytest.raises(nx.NetworkXError, nx.ring_of_cliques, 3, 0)
|
||||
|
||||
|
||||
def test_windmill_graph():
|
||||
for n in range(2, 20, 3):
|
||||
for k in range(2, 20, 3):
|
||||
G = nx.windmill_graph(n, k)
|
||||
assert G.number_of_nodes() == (k - 1) * n + 1
|
||||
assert G.number_of_edges() == n * k * (k - 1) / 2
|
||||
assert G.degree(0) == G.number_of_nodes() - 1
|
||||
for i in range(1, G.number_of_nodes()):
|
||||
assert G.degree(i) == k - 1
|
||||
pytest.raises(nx.NetworkXError, nx.ring_of_cliques, 1, 3)
|
||||
pytest.raises(nx.NetworkXError, nx.ring_of_cliques, 15, 0)
|
||||
|
||||
|
||||
def test_stochastic_block_model():
|
||||
sizes = [75, 75, 300]
|
||||
probs = [[0.25, 0.05, 0.02], [0.05, 0.35, 0.07], [0.02, 0.07, 0.40]]
|
||||
G = nx.stochastic_block_model(sizes, probs, seed=0)
|
||||
C = G.graph["partition"]
|
||||
assert len(C) == 3
|
||||
assert len(G) == 450
|
||||
assert G.size() == 22160
|
||||
|
||||
GG = nx.stochastic_block_model(sizes, probs, range(450), seed=0)
|
||||
assert G.nodes == GG.nodes
|
||||
|
||||
# Test Exceptions
|
||||
sbm = nx.stochastic_block_model
|
||||
badnodelist = list(range(400)) # not enough nodes to match sizes
|
||||
badprobs1 = [[0.25, 0.05, 1.02], [0.05, 0.35, 0.07], [0.02, 0.07, 0.40]]
|
||||
badprobs2 = [[0.25, 0.05, 0.02], [0.05, -0.35, 0.07], [0.02, 0.07, 0.40]]
|
||||
probs_rect1 = [[0.25, 0.05, 0.02], [0.05, -0.35, 0.07]]
|
||||
probs_rect2 = [[0.25, 0.05], [0.05, -0.35], [0.02, 0.07]]
|
||||
asymprobs = [[0.25, 0.05, 0.01], [0.05, -0.35, 0.07], [0.02, 0.07, 0.40]]
|
||||
pytest.raises(nx.NetworkXException, sbm, sizes, badprobs1)
|
||||
pytest.raises(nx.NetworkXException, sbm, sizes, badprobs2)
|
||||
pytest.raises(nx.NetworkXException, sbm, sizes, probs_rect1, directed=True)
|
||||
pytest.raises(nx.NetworkXException, sbm, sizes, probs_rect2, directed=True)
|
||||
pytest.raises(nx.NetworkXException, sbm, sizes, asymprobs, directed=False)
|
||||
pytest.raises(nx.NetworkXException, sbm, sizes, probs, badnodelist)
|
||||
nodelist = [0] + list(range(449)) # repeated node name in nodelist
|
||||
pytest.raises(nx.NetworkXException, sbm, sizes, probs, nodelist)
|
||||
|
||||
# Extra keyword arguments test
|
||||
GG = nx.stochastic_block_model(sizes, probs, seed=0, selfloops=True)
|
||||
assert G.nodes == GG.nodes
|
||||
GG = nx.stochastic_block_model(sizes, probs, selfloops=True, directed=True)
|
||||
assert G.nodes == GG.nodes
|
||||
GG = nx.stochastic_block_model(sizes, probs, seed=0, sparse=False)
|
||||
assert G.nodes == GG.nodes
|
||||
|
||||
|
||||
def test_generator():
|
||||
n = 250
|
||||
tau1 = 3
|
||||
tau2 = 1.5
|
||||
mu = 0.1
|
||||
G = nx.LFR_benchmark_graph(
|
||||
n, tau1, tau2, mu, average_degree=5, min_community=20, seed=10
|
||||
)
|
||||
assert len(G) == 250
|
||||
C = {frozenset(G.nodes[v]["community"]) for v in G}
|
||||
assert nx.community.is_partition(G.nodes(), C)
|
||||
|
||||
|
||||
def test_invalid_tau1():
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
n = 100
|
||||
tau1 = 2
|
||||
tau2 = 1
|
||||
mu = 0.1
|
||||
nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2)
|
||||
|
||||
|
||||
def test_invalid_tau2():
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
n = 100
|
||||
tau1 = 1
|
||||
tau2 = 2
|
||||
mu = 0.1
|
||||
nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2)
|
||||
|
||||
|
||||
def test_mu_too_large():
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
n = 100
|
||||
tau1 = 2
|
||||
tau2 = 2
|
||||
mu = 1.1
|
||||
nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2)
|
||||
|
||||
|
||||
def test_mu_too_small():
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
n = 100
|
||||
tau1 = 2
|
||||
tau2 = 2
|
||||
mu = -1
|
||||
nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2)
|
||||
|
||||
|
||||
def test_both_degrees_none():
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
n = 100
|
||||
tau1 = 2
|
||||
tau2 = 2
|
||||
mu = -1
|
||||
nx.LFR_benchmark_graph(n, tau1, tau2, mu)
|
||||
|
||||
|
||||
def test_neither_degrees_none():
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
n = 100
|
||||
tau1 = 2
|
||||
tau2 = 2
|
||||
mu = -1
|
||||
nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2, average_degree=5)
|
|
@ -0,0 +1,230 @@
|
|||
import pytest
|
||||
|
||||
import networkx as nx
|
||||
|
||||
|
||||
class TestConfigurationModel:
|
||||
"""Unit tests for the :func:`~networkx.configuration_model`
|
||||
function.
|
||||
|
||||
"""
|
||||
|
||||
def test_empty_degree_sequence(self):
|
||||
"""Tests that an empty degree sequence yields the null graph."""
|
||||
G = nx.configuration_model([])
|
||||
assert len(G) == 0
|
||||
|
||||
def test_degree_zero(self):
|
||||
"""Tests that a degree sequence of all zeros yields the empty
|
||||
graph.
|
||||
|
||||
"""
|
||||
G = nx.configuration_model([0, 0, 0])
|
||||
assert len(G) == 3
|
||||
assert G.number_of_edges() == 0
|
||||
|
||||
def test_degree_sequence(self):
|
||||
"""Tests that the degree sequence of the generated graph matches
|
||||
the input degree sequence.
|
||||
|
||||
"""
|
||||
deg_seq = [5, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1]
|
||||
G = nx.configuration_model(deg_seq, seed=12345678)
|
||||
assert sorted((d for n, d in G.degree()), reverse=True) == [
|
||||
5,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
]
|
||||
assert sorted((d for n, d in G.degree(range(len(deg_seq)))), reverse=True) == [
|
||||
5,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
]
|
||||
|
||||
def test_random_seed(self):
|
||||
"""Tests that each call with the same random seed generates the
|
||||
same graph.
|
||||
|
||||
"""
|
||||
deg_seq = [3] * 12
|
||||
G1 = nx.configuration_model(deg_seq, seed=1000)
|
||||
G2 = nx.configuration_model(deg_seq, seed=1000)
|
||||
assert nx.is_isomorphic(G1, G2)
|
||||
G1 = nx.configuration_model(deg_seq, seed=10)
|
||||
G2 = nx.configuration_model(deg_seq, seed=10)
|
||||
assert nx.is_isomorphic(G1, G2)
|
||||
|
||||
def test_directed_disallowed(self):
|
||||
"""Tests that attempting to create a configuration model graph
|
||||
using a directed graph yields an exception.
|
||||
|
||||
"""
|
||||
with pytest.raises(nx.NetworkXNotImplemented):
|
||||
nx.configuration_model([], create_using=nx.DiGraph())
|
||||
|
||||
def test_odd_degree_sum(self):
|
||||
"""Tests that a degree sequence whose sum is odd yields an
|
||||
exception.
|
||||
|
||||
"""
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
nx.configuration_model([1, 2])
|
||||
|
||||
|
||||
def test_directed_configuation_raise_unequal():
|
||||
with pytest.raises(nx.NetworkXError):
|
||||
zin = [5, 3, 3, 3, 3, 2, 2, 2, 1, 1]
|
||||
zout = [5, 3, 3, 3, 3, 2, 2, 2, 1, 2]
|
||||
nx.directed_configuration_model(zin, zout)
|
||||
|
||||
|
||||
def test_directed_configuation_model():
|
||||
G = nx.directed_configuration_model([], [], seed=0)
|
||||
assert len(G) == 0
|
||||
|
||||
|
||||
def test_simple_directed_configuation_model():
|
||||
G = nx.directed_configuration_model([1, 1], [1, 1], seed=0)
|
||||
assert len(G) == 2
|
||||
|
||||
|
||||
def test_expected_degree_graph_empty():
|
||||
# empty graph has empty degree sequence
|
||||
deg_seq = []
|
||||
G = nx.expected_degree_graph(deg_seq)
|
||||
assert dict(G.degree()) == {}
|
||||
|
||||
|
||||
def test_expected_degree_graph():
|
||||
# test that fixed seed delivers the same graph
|
||||
deg_seq = [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
|
||||
G1 = nx.expected_degree_graph(deg_seq, seed=1000)
|
||||
assert len(G1) == 12
|
||||
|
||||
G2 = nx.expected_degree_graph(deg_seq, seed=1000)
|
||||
assert nx.is_isomorphic(G1, G2)
|
||||
|
||||
G1 = nx.expected_degree_graph(deg_seq, seed=10)
|
||||
G2 = nx.expected_degree_graph(deg_seq, seed=10)
|
||||
assert nx.is_isomorphic(G1, G2)
|
||||
|
||||
|
||||
def test_expected_degree_graph_selfloops():
|
||||
deg_seq = [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
|
||||
G1 = nx.expected_degree_graph(deg_seq, seed=1000, selfloops=False)
|
||||
G2 = nx.expected_degree_graph(deg_seq, seed=1000, selfloops=False)
|
||||
assert nx.is_isomorphic(G1, G2)
|
||||
assert len(G1) == 12
|
||||
|
||||
|
||||
def test_expected_degree_graph_skew():
|
||||
deg_seq = [10, 2, 2, 2, 2]
|
||||
G1 = nx.expected_degree_graph(deg_seq, seed=1000)
|
||||
G2 = nx.expected_degree_graph(deg_seq, seed=1000)
|
||||
assert nx.is_isomorphic(G1, G2)
|
||||
assert len(G1) == 5
|
||||
|
||||
|
||||
def test_havel_hakimi_construction():
|
||||
G = nx.havel_hakimi_graph([])
|
||||
assert len(G) == 0
|
||||
|
||||
z = [1000, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1]
|
||||
pytest.raises(nx.NetworkXError, nx.havel_hakimi_graph, z)
|
||||
z = ["A", 3, 3, 3, 3, 2, 2, 2, 1, 1, 1]
|
||||
pytest.raises(nx.NetworkXError, nx.havel_hakimi_graph, z)
|
||||
|
||||
z = [5, 4, 3, 3, 3, 2, 2, 2]
|
||||
G = nx.havel_hakimi_graph(z)
|
||||
G = nx.configuration_model(z)
|
||||
z = [6, 5, 4, 4, 2, 1, 1, 1]
|
||||
pytest.raises(nx.NetworkXError, nx.havel_hakimi_graph, z)
|
||||
|
||||
z = [10, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2]
|
||||
|
||||
G = nx.havel_hakimi_graph(z)
|
||||
|
||||
pytest.raises(nx.NetworkXError, nx.havel_hakimi_graph, z, create_using=nx.DiGraph())
|
||||
|
||||
|
||||
def test_directed_havel_hakimi():
|
||||
# Test range of valid directed degree sequences
|
||||
n, r = 100, 10
|
||||
p = 1.0 / r
|
||||
for i in range(r):
|
||||
G1 = nx.erdos_renyi_graph(n, p * (i + 1), None, True)
|
||||
din1 = list(d for n, d in G1.in_degree())
|
||||
dout1 = list(d for n, d in G1.out_degree())
|
||||
G2 = nx.directed_havel_hakimi_graph(din1, dout1)
|
||||
din2 = list(d for n, d in G2.in_degree())
|
||||
dout2 = list(d for n, d in G2.out_degree())
|
||||
assert sorted(din1) == sorted(din2)
|
||||
assert sorted(dout1) == sorted(dout2)
|
||||
|
||||
# Test non-graphical sequence
|
||||
dout = [1000, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1]
|
||||
din = [103, 102, 102, 102, 102, 102, 102, 102, 102, 102]
|
||||
pytest.raises(nx.exception.NetworkXError, nx.directed_havel_hakimi_graph, din, dout)
|
||||
# Test valid sequences
|
||||
dout = [1, 1, 1, 1, 1, 2, 2, 2, 3, 4]
|
||||
din = [2, 2, 2, 2, 2, 2, 2, 2, 0, 2]
|
||||
G2 = nx.directed_havel_hakimi_graph(din, dout)
|
||||
dout2 = (d for n, d in G2.out_degree())
|
||||
din2 = (d for n, d in G2.in_degree())
|
||||
assert sorted(dout) == sorted(dout2)
|
||||
assert sorted(din) == sorted(din2)
|
||||
# Test unequal sums
|
||||
din = [2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
|
||||
pytest.raises(nx.exception.NetworkXError, nx.directed_havel_hakimi_graph, din, dout)
|
||||
# Test for negative values
|
||||
din = [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2]
|
||||
pytest.raises(nx.exception.NetworkXError, nx.directed_havel_hakimi_graph, din, dout)
|
||||
|
||||
|
||||
def test_degree_sequence_tree():
|
||||
z = [1, 1, 1, 1, 1, 2, 2, 2, 3, 4]
|
||||
G = nx.degree_sequence_tree(z)
|
||||
assert len(G) == len(z)
|
||||
assert len(list(G.edges())) == sum(z) / 2
|
||||
|
||||
pytest.raises(
|
||||
nx.NetworkXError, nx.degree_sequence_tree, z, create_using=nx.DiGraph()
|
||||
)
|
||||
|
||||
z = [1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4]
|
||||
pytest.raises(nx.NetworkXError, nx.degree_sequence_tree, z)
|
||||
|
||||
|
||||
def test_random_degree_sequence_graph():
|
||||
d = [1, 2, 2, 3]
|
||||
G = nx.random_degree_sequence_graph(d, seed=42)
|
||||
assert d == sorted(d for n, d in G.degree())
|
||||
|
||||
|
||||
def test_random_degree_sequence_graph_raise():
|
||||
z = [1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4]
|
||||
pytest.raises(nx.NetworkXUnfeasible, nx.random_degree_sequence_graph, z)
|
||||
|
||||
|
||||
def test_random_degree_sequence_large():
|
||||
G1 = nx.fast_gnp_random_graph(100, 0.1, seed=42)
|
||||
d1 = (d for n, d in G1.degree())
|
||||
G2 = nx.random_degree_sequence_graph(d1, seed=42)
|
||||
d2 = (d for n, d in G2.degree())
|
||||
assert sorted(d1) == sorted(d2)
|
|
@ -0,0 +1,121 @@
|
|||
"""Generators - Directed Graphs
|
||||
----------------------------
|
||||
"""
|
||||
import pytest
|
||||
|
||||
import networkx as nx
|
||||
from networkx.classes import Graph
|
||||
from networkx.classes import MultiDiGraph
|
||||
from networkx.generators.directed import gn_graph
|
||||
from networkx.generators.directed import gnr_graph
|
||||
from networkx.generators.directed import gnc_graph
|
||||
from networkx.generators.directed import random_k_out_graph
|
||||
from networkx.generators.directed import random_uniform_k_out_graph
|
||||
from networkx.generators.directed import scale_free_graph
|
||||
|
||||
|
||||
class TestGeneratorsDirected:
|
||||
def test_smoke_test_random_graphs(self):
|
||||
gn_graph(100)
|
||||
gnr_graph(100, 0.5)
|
||||
gnc_graph(100)
|
||||
scale_free_graph(100)
|
||||
|
||||
gn_graph(100, seed=42)
|
||||
gnr_graph(100, 0.5, seed=42)
|
||||
gnc_graph(100, seed=42)
|
||||
scale_free_graph(100, seed=42)
|
||||
|
||||
def test_create_using_keyword_arguments(self):
|
||||
pytest.raises(nx.NetworkXError, gn_graph, 100, create_using=Graph())
|
||||
pytest.raises(nx.NetworkXError, gnr_graph, 100, 0.5, create_using=Graph())
|
||||
pytest.raises(nx.NetworkXError, gnc_graph, 100, create_using=Graph())
|
||||
pytest.raises(nx.NetworkXError, scale_free_graph, 100, create_using=Graph())
|
||||
G = gn_graph(100, seed=1)
|
||||
MG = gn_graph(100, create_using=MultiDiGraph(), seed=1)
|
||||
assert sorted(G.edges()) == sorted(MG.edges())
|
||||
G = gnr_graph(100, 0.5, seed=1)
|
||||
MG = gnr_graph(100, 0.5, create_using=MultiDiGraph(), seed=1)
|
||||
assert sorted(G.edges()) == sorted(MG.edges())
|
||||
G = gnc_graph(100, seed=1)
|
||||
MG = gnc_graph(100, create_using=MultiDiGraph(), seed=1)
|
||||
assert sorted(G.edges()) == sorted(MG.edges())
|
||||
|
||||
G = scale_free_graph(
|
||||
100,
|
||||
alpha=0.3,
|
||||
beta=0.4,
|
||||
gamma=0.3,
|
||||
delta_in=0.3,
|
||||
delta_out=0.1,
|
||||
create_using=MultiDiGraph,
|
||||
seed=1,
|
||||
)
|
||||
pytest.raises(ValueError, scale_free_graph, 100, 0.5, 0.4, 0.3)
|
||||
pytest.raises(ValueError, scale_free_graph, 100, alpha=-0.3)
|
||||
pytest.raises(ValueError, scale_free_graph, 100, beta=-0.3)
|
||||
pytest.raises(ValueError, scale_free_graph, 100, gamma=-0.3)
|
||||
|
||||
|
||||
class TestRandomKOutGraph:
|
||||
"""Unit tests for the
|
||||
:func:`~networkx.generators.directed.random_k_out_graph` function.
|
||||
|
||||
"""
|
||||
|
||||
def test_regularity(self):
|
||||
"""Tests that the generated graph is `k`-out-regular."""
|
||||
n = 10
|
||||
k = 3
|
||||
alpha = 1
|
||||
G = random_k_out_graph(n, k, alpha)
|
||||
assert all(d == k for v, d in G.out_degree())
|
||||
G = random_k_out_graph(n, k, alpha, seed=42)
|
||||
assert all(d == k for v, d in G.out_degree())
|
||||
|
||||
def test_no_self_loops(self):
|
||||
"""Tests for forbidding self-loops."""
|
||||
n = 10
|
||||
k = 3
|
||||
alpha = 1
|
||||
G = random_k_out_graph(n, k, alpha, self_loops=False)
|
||||
assert nx.number_of_selfloops(G) == 0
|
||||
|
||||
|
||||
class TestUniformRandomKOutGraph:
|
||||
"""Unit tests for the
|
||||
:func:`~networkx.generators.directed.random_uniform_k_out_graph`
|
||||
function.
|
||||
|
||||
"""
|
||||
|
||||
def test_regularity(self):
|
||||
"""Tests that the generated graph is `k`-out-regular."""
|
||||
n = 10
|
||||
k = 3
|
||||
G = random_uniform_k_out_graph(n, k)
|
||||
assert all(d == k for v, d in G.out_degree())
|
||||
G = random_uniform_k_out_graph(n, k, seed=42)
|
||||
assert all(d == k for v, d in G.out_degree())
|
||||
|
||||
def test_no_self_loops(self):
|
||||
"""Tests for forbidding self-loops."""
|
||||
n = 10
|
||||
k = 3
|
||||
G = random_uniform_k_out_graph(n, k, self_loops=False)
|
||||
assert nx.number_of_selfloops(G) == 0
|
||||
assert all(d == k for v, d in G.out_degree())
|
||||
|
||||
def test_with_replacement(self):
|
||||
n = 10
|
||||
k = 3
|
||||
G = random_uniform_k_out_graph(n, k, with_replacement=True)
|
||||
assert G.is_multigraph()
|
||||
assert all(d == k for v, d in G.out_degree())
|
||||
|
||||
def test_without_replacement(self):
|
||||
n = 10
|
||||
k = 3
|
||||
G = random_uniform_k_out_graph(n, k, with_replacement=False)
|
||||
assert not G.is_multigraph()
|
||||
assert all(d == k for v, d in G.out_degree())
|
|
@ -0,0 +1,71 @@
|
|||
"""Unit tests for the :mod:`networkx.generators.duplication` module.
|
||||
|
||||
"""
|
||||
import pytest
|
||||
|
||||
from networkx.exception import NetworkXError
|
||||
from networkx.generators.duplication import duplication_divergence_graph
|
||||
from networkx.generators.duplication import partial_duplication_graph
|
||||
|
||||
|
||||
class TestDuplicationDivergenceGraph:
|
||||
"""Unit tests for the
|
||||
:func:`networkx.generators.duplication.duplication_divergence_graph`
|
||||
function.
|
||||
|
||||
"""
|
||||
|
||||
def test_final_size(self):
|
||||
G = duplication_divergence_graph(3, 1)
|
||||
assert len(G) == 3
|
||||
G = duplication_divergence_graph(3, 1, seed=42)
|
||||
assert len(G) == 3
|
||||
|
||||
def test_probability_too_large(self):
|
||||
with pytest.raises(NetworkXError):
|
||||
duplication_divergence_graph(3, 2)
|
||||
|
||||
def test_probability_too_small(self):
|
||||
with pytest.raises(NetworkXError):
|
||||
duplication_divergence_graph(3, -1)
|
||||
|
||||
|
||||
class TestPartialDuplicationGraph:
|
||||
"""Unit tests for the
|
||||
:func:`networkx.generators.duplication.partial_duplication_graph`
|
||||
function.
|
||||
|
||||
"""
|
||||
|
||||
def test_final_size(self):
|
||||
N = 10
|
||||
n = 5
|
||||
p = 0.5
|
||||
q = 0.5
|
||||
G = partial_duplication_graph(N, n, p, q)
|
||||
assert len(G) == N
|
||||
G = partial_duplication_graph(N, n, p, q, seed=42)
|
||||
assert len(G) == N
|
||||
|
||||
def test_initial_clique_size(self):
|
||||
N = 10
|
||||
n = 10
|
||||
p = 0.5
|
||||
q = 0.5
|
||||
G = partial_duplication_graph(N, n, p, q)
|
||||
assert len(G) == n
|
||||
|
||||
def test_invalid_initial_size(self):
|
||||
with pytest.raises(NetworkXError):
|
||||
N = 5
|
||||
n = 10
|
||||
p = 0.5
|
||||
q = 0.5
|
||||
G = partial_duplication_graph(N, n, p, q)
|
||||
|
||||
def test_invalid_probabilities(self):
|
||||
N = 1
|
||||
n = 1
|
||||
for p, q in [(0.5, 2), (0.5, -1), (2, 0.5), (-1, 0.5)]:
|
||||
args = (N, n, p, q)
|
||||
pytest.raises(NetworkXError, partial_duplication_graph, *args)
|
39
venv/Lib/site-packages/networkx/generators/tests/test_ego.py
Normal file
39
venv/Lib/site-packages/networkx/generators/tests/test_ego.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
"""
|
||||
ego graph
|
||||
---------
|
||||
"""
|
||||
|
||||
import networkx as nx
|
||||
from networkx.testing.utils import assert_edges_equal, assert_nodes_equal
|
||||
|
||||
|
||||
class TestGeneratorEgo:
|
||||
def test_ego(self):
|
||||
G = nx.star_graph(3)
|
||||
H = nx.ego_graph(G, 0)
|
||||
assert nx.is_isomorphic(G, H)
|
||||
G.add_edge(1, 11)
|
||||
G.add_edge(2, 22)
|
||||
G.add_edge(3, 33)
|
||||
H = nx.ego_graph(G, 0)
|
||||
assert nx.is_isomorphic(nx.star_graph(3), H)
|
||||
G = nx.path_graph(3)
|
||||
H = nx.ego_graph(G, 0)
|
||||
assert_edges_equal(H.edges(), [(0, 1)])
|
||||
H = nx.ego_graph(G, 0, undirected=True)
|
||||
assert_edges_equal(H.edges(), [(0, 1)])
|
||||
H = nx.ego_graph(G, 0, center=False)
|
||||
assert_edges_equal(H.edges(), [])
|
||||
|
||||
def test_ego_distance(self):
|
||||
G = nx.Graph()
|
||||
G.add_edge(0, 1, weight=2, distance=1)
|
||||
G.add_edge(1, 2, weight=2, distance=2)
|
||||
G.add_edge(2, 3, weight=2, distance=1)
|
||||
assert_nodes_equal(nx.ego_graph(G, 0, radius=3).nodes(), [0, 1, 2, 3])
|
||||
eg = nx.ego_graph(G, 0, radius=3, distance="weight")
|
||||
assert_nodes_equal(eg.nodes(), [0, 1])
|
||||
eg = nx.ego_graph(G, 0, radius=3, distance="weight", undirected=True)
|
||||
assert_nodes_equal(eg.nodes(), [0, 1])
|
||||
eg = nx.ego_graph(G, 0, radius=3, distance="distance")
|
||||
assert_nodes_equal(eg.nodes(), [0, 1, 2])
|
|
@ -0,0 +1,71 @@
|
|||
"""Unit tests for the :mod:`networkx.generators.expanders` module.
|
||||
|
||||
"""
|
||||
|
||||
import networkx as nx
|
||||
from networkx import adjacency_matrix
|
||||
from networkx import number_of_nodes
|
||||
from networkx.generators.expanders import chordal_cycle_graph
|
||||
from networkx.generators.expanders import margulis_gabber_galil_graph
|
||||
from networkx.generators.expanders import paley_graph
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_margulis_gabber_galil_graph():
|
||||
for n in 2, 3, 5, 6, 10:
|
||||
g = margulis_gabber_galil_graph(n)
|
||||
assert number_of_nodes(g) == n * n
|
||||
for node in g:
|
||||
assert g.degree(node) == 8
|
||||
assert len(node) == 2
|
||||
for i in node:
|
||||
assert int(i) == i
|
||||
assert 0 <= i < n
|
||||
|
||||
np = pytest.importorskip("numpy")
|
||||
scipy = pytest.importorskip("scipy")
|
||||
scipy.linalg = pytest.importorskip("scipy.linalg")
|
||||
# Eigenvalues are already sorted using the scipy eigvalsh,
|
||||
# but the implementation in numpy does not guarantee order.
|
||||
w = sorted(scipy.linalg.eigvalsh(adjacency_matrix(g).A))
|
||||
assert w[-2] < 5 * np.sqrt(2)
|
||||
|
||||
|
||||
def test_chordal_cycle_graph():
|
||||
"""Test for the :func:`networkx.chordal_cycle_graph` function."""
|
||||
primes = [3, 5, 7, 11]
|
||||
for p in primes:
|
||||
G = chordal_cycle_graph(p)
|
||||
assert len(G) == p
|
||||
# TODO The second largest eigenvalue should be smaller than a constant,
|
||||
# independent of the number of nodes in the graph:
|
||||
#
|
||||
# eigs = sorted(scipy.linalg.eigvalsh(adjacency_matrix(G).A))
|
||||
# assert_less(eigs[-2], ...)
|
||||
#
|
||||
|
||||
|
||||
def test_paley_graph():
|
||||
"""Test for the :func:`networkx.paley_graph` function."""
|
||||
primes = [3, 5, 7, 11, 13]
|
||||
for p in primes:
|
||||
G = paley_graph(p)
|
||||
# G has p nodes
|
||||
assert len(G) == p
|
||||
# G is (p-1)/2-regular
|
||||
in_degrees = {G.in_degree(node) for node in G.nodes}
|
||||
out_degrees = {G.out_degree(node) for node in G.nodes}
|
||||
assert len(in_degrees) == 1 and in_degrees.pop() == (p - 1) // 2
|
||||
assert len(out_degrees) == 1 and out_degrees.pop() == (p - 1) // 2
|
||||
|
||||
# If p = 1 mod 4, -1 is a square mod 4 and therefore the
|
||||
# edge in the Paley graph are symmetric.
|
||||
if p % 4 == 1:
|
||||
for (u, v) in G.edges:
|
||||
assert (v, u) in G.edges
|
||||
|
||||
|
||||
def test_margulis_gabber_galil_graph_badinput():
|
||||
pytest.raises(nx.NetworkXError, margulis_gabber_galil_graph, 3, nx.DiGraph())
|
||||
pytest.raises(nx.NetworkXError, margulis_gabber_galil_graph, 3, nx.Graph())
|
|
@ -0,0 +1,350 @@
|
|||
from itertools import combinations
|
||||
from math import sqrt
|
||||
import random
|
||||
|
||||
|
||||
import networkx as nx
|
||||
from networkx.generators.geometric import euclidean
|
||||
|
||||
|
||||
def l1dist(x, y):
|
||||
return sum(abs(a - b) for a, b in zip(x, y))
|
||||
|
||||
|
||||
class TestRandomGeometricGraph:
|
||||
"""Unit tests for the :func:`~networkx.random_geometric_graph`
|
||||
function.
|
||||
|
||||
"""
|
||||
|
||||
def test_number_of_nodes(self):
|
||||
G = nx.random_geometric_graph(50, 0.25, seed=42)
|
||||
assert len(G) == 50
|
||||
G = nx.random_geometric_graph(range(50), 0.25, seed=42)
|
||||
assert len(G) == 50
|
||||
|
||||
def test_distances(self):
|
||||
"""Tests that pairs of vertices adjacent if and only if they are
|
||||
within the prescribed radius.
|
||||
|
||||
"""
|
||||
# Use the Euclidean metric, the default according to the
|
||||
# documentation.
|
||||
dist = euclidean
|
||||
G = nx.random_geometric_graph(50, 0.25)
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must be within the given distance.
|
||||
if v in G[u]:
|
||||
assert dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
# Nonadjacent vertices must be at greater distance.
|
||||
else:
|
||||
assert not dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
|
||||
def test_p(self):
|
||||
"""Tests for providing an alternate distance metric to the
|
||||
generator.
|
||||
|
||||
"""
|
||||
# Use the L1 metric.
|
||||
dist = l1dist
|
||||
G = nx.random_geometric_graph(50, 0.25, p=1)
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must be within the given distance.
|
||||
if v in G[u]:
|
||||
assert dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
# Nonadjacent vertices must be at greater distance.
|
||||
else:
|
||||
assert not dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
|
||||
def test_node_names(self):
|
||||
"""Tests using values other than sequential numbers as node IDs.
|
||||
|
||||
"""
|
||||
import string
|
||||
|
||||
nodes = list(string.ascii_lowercase)
|
||||
G = nx.random_geometric_graph(nodes, 0.25)
|
||||
assert len(G) == len(nodes)
|
||||
|
||||
dist = euclidean
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must be within the given distance.
|
||||
if v in G[u]:
|
||||
assert dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
# Nonadjacent vertices must be at greater distance.
|
||||
else:
|
||||
assert not dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
|
||||
|
||||
class TestSoftRandomGeometricGraph:
|
||||
"""Unit tests for the :func:`~networkx.soft_random_geometric_graph`
|
||||
function.
|
||||
|
||||
"""
|
||||
|
||||
def test_number_of_nodes(self):
|
||||
G = nx.soft_random_geometric_graph(50, 0.25, seed=42)
|
||||
assert len(G) == 50
|
||||
G = nx.soft_random_geometric_graph(range(50), 0.25, seed=42)
|
||||
assert len(G) == 50
|
||||
|
||||
def test_distances(self):
|
||||
"""Tests that pairs of vertices adjacent if and only if they are
|
||||
within the prescribed radius.
|
||||
|
||||
"""
|
||||
# Use the Euclidean metric, the default according to the
|
||||
# documentation.
|
||||
def dist(x, y):
|
||||
return sqrt(sum((a - b) ** 2 for a, b in zip(x, y)))
|
||||
|
||||
G = nx.soft_random_geometric_graph(50, 0.25)
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must be within the given distance.
|
||||
if v in G[u]:
|
||||
assert dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
|
||||
def test_p(self):
|
||||
"""Tests for providing an alternate distance metric to the
|
||||
generator.
|
||||
|
||||
"""
|
||||
# Use the L1 metric.
|
||||
def dist(x, y):
|
||||
return sum(abs(a - b) for a, b in zip(x, y))
|
||||
|
||||
G = nx.soft_random_geometric_graph(50, 0.25, p=1)
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must be within the given distance.
|
||||
if v in G[u]:
|
||||
assert dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
|
||||
def test_node_names(self):
|
||||
"""Tests using values other than sequential numbers as node IDs.
|
||||
|
||||
"""
|
||||
import string
|
||||
|
||||
nodes = list(string.ascii_lowercase)
|
||||
G = nx.soft_random_geometric_graph(nodes, 0.25)
|
||||
assert len(G) == len(nodes)
|
||||
|
||||
def dist(x, y):
|
||||
return sqrt(sum((a - b) ** 2 for a, b in zip(x, y)))
|
||||
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must be within the given distance.
|
||||
if v in G[u]:
|
||||
assert dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
|
||||
def test_p_dist_default(self):
|
||||
"""Tests default p_dict = 0.5 returns graph with edge count <= RGG with
|
||||
same n, radius, dim and positions
|
||||
|
||||
"""
|
||||
nodes = 50
|
||||
dim = 2
|
||||
pos = {v: [random.random() for i in range(dim)] for v in range(nodes)}
|
||||
RGG = nx.random_geometric_graph(50, 0.25, pos=pos)
|
||||
SRGG = nx.soft_random_geometric_graph(50, 0.25, pos=pos)
|
||||
assert len(SRGG.edges()) <= len(RGG.edges())
|
||||
|
||||
def test_p_dist_zero(self):
|
||||
"""Tests if p_dict = 0 returns disconencted graph with 0 edges
|
||||
|
||||
"""
|
||||
|
||||
def p_dist(dist):
|
||||
return 0
|
||||
|
||||
G = nx.soft_random_geometric_graph(50, 0.25, p_dist=p_dist)
|
||||
assert len(G.edges) == 0
|
||||
|
||||
|
||||
def join(G, u, v, theta, alpha, metric):
|
||||
"""Returns ``True`` if and only if the nodes whose attributes are
|
||||
``du`` and ``dv`` should be joined, according to the threshold
|
||||
condition for geographical threshold graphs.
|
||||
|
||||
``G`` is an undirected NetworkX graph, and ``u`` and ``v`` are nodes
|
||||
in that graph. The nodes must have node attributes ``'pos'`` and
|
||||
``'weight'``.
|
||||
|
||||
``metric`` is a distance metric.
|
||||
|
||||
"""
|
||||
du, dv = G.nodes[u], G.nodes[v]
|
||||
u_pos, v_pos = du["pos"], dv["pos"]
|
||||
u_weight, v_weight = du["weight"], dv["weight"]
|
||||
return (u_weight + v_weight) * metric(u_pos, v_pos) ** alpha >= theta
|
||||
|
||||
|
||||
class TestGeographicalThresholdGraph:
|
||||
"""Unit tests for the :func:`~networkx.geographical_threshold_graph`
|
||||
function.
|
||||
|
||||
"""
|
||||
|
||||
def test_number_of_nodes(self):
|
||||
G = nx.geographical_threshold_graph(50, 100, seed=42)
|
||||
assert len(G) == 50
|
||||
G = nx.geographical_threshold_graph(range(50), 100, seed=42)
|
||||
assert len(G) == 50
|
||||
|
||||
def test_distances(self):
|
||||
"""Tests that pairs of vertices adjacent if and only if their
|
||||
distances meet the given threshold.
|
||||
|
||||
"""
|
||||
# Use the Euclidean metric and alpha = -2
|
||||
# the default according to the documentation.
|
||||
dist = euclidean
|
||||
G = nx.geographical_threshold_graph(50, 10)
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must exceed the threshold.
|
||||
if v in G[u]:
|
||||
assert join(G, u, v, 10, -2, dist)
|
||||
# Nonadjacent vertices must not exceed the threshold.
|
||||
else:
|
||||
assert not join(G, u, v, 10, -2, dist)
|
||||
|
||||
def test_metric(self):
|
||||
"""Tests for providing an alternate distance metric to the
|
||||
generator.
|
||||
|
||||
"""
|
||||
# Use the L1 metric.
|
||||
dist = l1dist
|
||||
G = nx.geographical_threshold_graph(50, 10, metric=dist)
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must exceed the threshold.
|
||||
if v in G[u]:
|
||||
assert join(G, u, v, 10, -2, dist)
|
||||
# Nonadjacent vertices must not exceed the threshold.
|
||||
else:
|
||||
assert not join(G, u, v, 10, -2, dist)
|
||||
|
||||
def test_p_dist_zero(self):
|
||||
"""Tests if p_dict = 0 returns disconencted graph with 0 edges
|
||||
|
||||
"""
|
||||
|
||||
def p_dist(dist):
|
||||
return 0
|
||||
|
||||
G = nx.geographical_threshold_graph(50, 1, p_dist=p_dist)
|
||||
assert len(G.edges) == 0
|
||||
|
||||
|
||||
class TestWaxmanGraph:
|
||||
"""Unit tests for the :func:`~networkx.waxman_graph` function."""
|
||||
|
||||
def test_number_of_nodes_1(self):
|
||||
G = nx.waxman_graph(50, 0.5, 0.1, seed=42)
|
||||
assert len(G) == 50
|
||||
G = nx.waxman_graph(range(50), 0.5, 0.1, seed=42)
|
||||
assert len(G) == 50
|
||||
|
||||
def test_number_of_nodes_2(self):
|
||||
G = nx.waxman_graph(50, 0.5, 0.1, L=1)
|
||||
assert len(G) == 50
|
||||
G = nx.waxman_graph(range(50), 0.5, 0.1, L=1)
|
||||
assert len(G) == 50
|
||||
|
||||
def test_metric(self):
|
||||
"""Tests for providing an alternate distance metric to the
|
||||
generator.
|
||||
|
||||
"""
|
||||
# Use the L1 metric.
|
||||
dist = l1dist
|
||||
G = nx.waxman_graph(50, 0.5, 0.1, metric=dist)
|
||||
assert len(G) == 50
|
||||
|
||||
|
||||
class TestNavigableSmallWorldGraph:
|
||||
def test_navigable_small_world(self):
|
||||
G = nx.navigable_small_world_graph(5, p=1, q=0, seed=42)
|
||||
gg = nx.grid_2d_graph(5, 5).to_directed()
|
||||
assert nx.is_isomorphic(G, gg)
|
||||
|
||||
G = nx.navigable_small_world_graph(5, p=1, q=0, dim=3)
|
||||
gg = nx.grid_graph([5, 5, 5]).to_directed()
|
||||
assert nx.is_isomorphic(G, gg)
|
||||
|
||||
G = nx.navigable_small_world_graph(5, p=1, q=0, dim=1)
|
||||
gg = nx.grid_graph([5]).to_directed()
|
||||
assert nx.is_isomorphic(G, gg)
|
||||
|
||||
|
||||
class TestThresholdedRandomGeometricGraph:
|
||||
"""Unit tests for the :func:`~networkx.thresholded_random_geometric_graph`
|
||||
function.
|
||||
|
||||
"""
|
||||
|
||||
def test_number_of_nodes(self):
|
||||
G = nx.thresholded_random_geometric_graph(50, 0.2, 0.1, seed=42)
|
||||
assert len(G) == 50
|
||||
G = nx.thresholded_random_geometric_graph(range(50), 0.2, 0.1)
|
||||
assert len(G) == 50
|
||||
|
||||
def test_distances(self):
|
||||
"""Tests that pairs of vertices adjacent if and only if they are
|
||||
within the prescribed radius.
|
||||
|
||||
"""
|
||||
# Use the Euclidean metric, the default according to the
|
||||
# documentation.
|
||||
def dist(x, y):
|
||||
return sqrt(sum((a - b) ** 2 for a, b in zip(x, y)))
|
||||
|
||||
G = nx.thresholded_random_geometric_graph(50, 0.25, 0.1)
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must be within the given distance.
|
||||
if v in G[u]:
|
||||
assert dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
|
||||
def test_p(self):
|
||||
"""Tests for providing an alternate distance metric to the
|
||||
generator.
|
||||
|
||||
"""
|
||||
# Use the L1 metric.
|
||||
def dist(x, y):
|
||||
return sum(abs(a - b) for a, b in zip(x, y))
|
||||
|
||||
G = nx.thresholded_random_geometric_graph(50, 0.25, 0.1, p=1)
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must be within the given distance.
|
||||
if v in G[u]:
|
||||
assert dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
|
||||
def test_node_names(self):
|
||||
"""Tests using values other than sequential numbers as node IDs.
|
||||
|
||||
"""
|
||||
import string
|
||||
|
||||
nodes = list(string.ascii_lowercase)
|
||||
G = nx.thresholded_random_geometric_graph(nodes, 0.25, 0.1)
|
||||
assert len(G) == len(nodes)
|
||||
|
||||
def dist(x, y):
|
||||
return sqrt(sum((a - b) ** 2 for a, b in zip(x, y)))
|
||||
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must be within the given distance.
|
||||
if v in G[u]:
|
||||
assert dist(G.nodes[u]["pos"], G.nodes[v]["pos"]) <= 0.25
|
||||
|
||||
def test_theta(self):
|
||||
"""Tests that pairs of vertices adjacent if and only if their sum
|
||||
weights exceeds the threshold parameter theta.
|
||||
"""
|
||||
G = nx.thresholded_random_geometric_graph(50, 0.25, 0.1)
|
||||
|
||||
for u, v in combinations(G, 2):
|
||||
# Adjacent vertices must be within the given distance.
|
||||
if v in G[u]:
|
||||
assert (G.nodes[u]["weight"] + G.nodes[v]["weight"]) >= 0.1
|
|
@ -0,0 +1,135 @@
|
|||
"""Unit tests for the :mod:`networkx.generators.harary_graph` module.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
import networkx as nx
|
||||
from networkx.generators.harary_graph import hnm_harary_graph
|
||||
from networkx.generators.harary_graph import hkn_harary_graph
|
||||
from networkx.algorithms.isomorphism.isomorph import is_isomorphic
|
||||
|
||||
|
||||
class TestHararyGraph:
|
||||
"""
|
||||
Suppose n nodes, m >= n-1 edges, d = 2m // n, r = 2m % n
|
||||
"""
|
||||
|
||||
def test_hnm_harary_graph(self):
|
||||
# When d is even and r = 0, the hnm_harary_graph(n,m) is
|
||||
# the circulant_graph(n, list(range(1,d/2+1)))
|
||||
for (n, m) in [(5, 5), (6, 12), (7, 14)]:
|
||||
G1 = hnm_harary_graph(n, m)
|
||||
d = 2 * m // n
|
||||
G2 = nx.circulant_graph(n, list(range(1, d // 2 + 1)))
|
||||
assert is_isomorphic(G1, G2)
|
||||
|
||||
# When d is even and r > 0, the hnm_harary_graph(n,m) is
|
||||
# the circulant_graph(n, list(range(1,d/2+1)))
|
||||
# with r edges added arbitrarily
|
||||
for (n, m) in [(5, 7), (6, 13), (7, 16)]:
|
||||
G1 = hnm_harary_graph(n, m)
|
||||
d = 2 * m // n
|
||||
G2 = nx.circulant_graph(n, list(range(1, d // 2 + 1)))
|
||||
assert set(G2.edges) < set(G1.edges)
|
||||
assert G1.number_of_edges() == m
|
||||
|
||||
# When d is odd and n is even and r = 0, the hnm_harary_graph(n,m)
|
||||
# is the circulant_graph(n, list(range(1,(d+1)/2) plus [n//2])
|
||||
for (n, m) in [(6, 9), (8, 12), (10, 15)]:
|
||||
G1 = hnm_harary_graph(n, m)
|
||||
d = 2 * m // n
|
||||
L = list(range(1, (d + 1) // 2))
|
||||
L.append(n // 2)
|
||||
G2 = nx.circulant_graph(n, L)
|
||||
assert is_isomorphic(G1, G2)
|
||||
|
||||
# When d is odd and n is even and r > 0, the hnm_harary_graph(n,m)
|
||||
# is the circulant_graph(n, list(range(1,(d+1)/2) plus [n//2])
|
||||
# with r edges added arbitrarily
|
||||
for (n, m) in [(6, 10), (8, 13), (10, 17)]:
|
||||
G1 = hnm_harary_graph(n, m)
|
||||
d = 2 * m // n
|
||||
L = list(range(1, (d + 1) // 2))
|
||||
L.append(n // 2)
|
||||
G2 = nx.circulant_graph(n, L)
|
||||
assert set(G2.edges) < set(G1.edges)
|
||||
assert G1.number_of_edges() == m
|
||||
|
||||
# When d is odd and n is odd, the hnm_harary_graph(n,m) is
|
||||
# the circulant_graph(n, list(range(1,(d+1)/2))
|
||||
# with m - n*(d-1)/2 edges added arbitrarily
|
||||
for (n, m) in [(5, 4), (7, 12), (9, 14)]:
|
||||
G1 = hnm_harary_graph(n, m)
|
||||
d = 2 * m // n
|
||||
L = list(range(1, (d + 1) // 2))
|
||||
G2 = nx.circulant_graph(n, L)
|
||||
assert set(G2.edges) < set(G1.edges)
|
||||
assert G1.number_of_edges() == m
|
||||
|
||||
# Raise NetworkXError if n<1
|
||||
n = 0
|
||||
m = 0
|
||||
pytest.raises(nx.NetworkXError, hnm_harary_graph, n, m)
|
||||
|
||||
# Raise NetworkXError if m < n-1
|
||||
n = 6
|
||||
m = 4
|
||||
pytest.raises(nx.NetworkXError, hnm_harary_graph, n, m)
|
||||
|
||||
# Raise NetworkXError if m > n(n-1)/2
|
||||
n = 6
|
||||
m = 16
|
||||
pytest.raises(nx.NetworkXError, hnm_harary_graph, n, m)
|
||||
|
||||
"""
|
||||
Suppose connectivity k, number of nodes n
|
||||
"""
|
||||
|
||||
def test_hkn_harary_graph(self):
|
||||
# When k == 1, the hkn_harary_graph(k,n) is
|
||||
# the path_graph(n)
|
||||
for (k, n) in [(1, 6), (1, 7)]:
|
||||
G1 = hkn_harary_graph(k, n)
|
||||
G2 = nx.path_graph(n)
|
||||
assert is_isomorphic(G1, G2)
|
||||
|
||||
# When k is even, the hkn_harary_graph(k,n) is
|
||||
# the circulant_graph(n, list(range(1,k/2+1)))
|
||||
for (k, n) in [(2, 6), (2, 7), (4, 6), (4, 7)]:
|
||||
G1 = hkn_harary_graph(k, n)
|
||||
G2 = nx.circulant_graph(n, list(range(1, k // 2 + 1)))
|
||||
assert is_isomorphic(G1, G2)
|
||||
|
||||
# When k is odd and n is even, the hkn_harary_graph(k,n) is
|
||||
# the circulant_graph(n, list(range(1,(k+1)/2)) plus [n/2])
|
||||
for (k, n) in [(3, 6), (5, 8), (7, 10)]:
|
||||
G1 = hkn_harary_graph(k, n)
|
||||
L = list(range(1, (k + 1) // 2))
|
||||
L.append(n // 2)
|
||||
G2 = nx.circulant_graph(n, L)
|
||||
assert is_isomorphic(G1, G2)
|
||||
|
||||
# When k is odd and n is odd, the hkn_harary_graph(k,n) is
|
||||
# the circulant_graph(n, list(range(1,(k+1)/2))) with
|
||||
# n//2+1 edges added between node i and node i+n//2+1
|
||||
for (k, n) in [(3, 5), (5, 9), (7, 11)]:
|
||||
G1 = hkn_harary_graph(k, n)
|
||||
G2 = nx.circulant_graph(n, list(range(1, (k + 1) // 2)))
|
||||
eSet1 = set(G1.edges)
|
||||
eSet2 = set(G2.edges)
|
||||
eSet3 = set()
|
||||
half = n // 2
|
||||
for i in range(0, half + 1):
|
||||
# add half+1 edges between i and i+half
|
||||
eSet3.add((i, (i + half) % n))
|
||||
assert eSet1 == eSet2 | eSet3
|
||||
|
||||
# Raise NetworkXError if k<1
|
||||
k = 0
|
||||
n = 0
|
||||
pytest.raises(nx.NetworkXError, hkn_harary_graph, k, n)
|
||||
|
||||
# Raise NetworkXError if n<k+1
|
||||
k = 6
|
||||
n = 6
|
||||
pytest.raises(nx.NetworkXError, hkn_harary_graph, k, n)
|
|
@ -0,0 +1,189 @@
|
|||
from networkx import is_connected, neighbors
|
||||
from networkx.generators.internet_as_graphs import random_internet_as_graph
|
||||
from networkx.testing import almost_equal
|
||||
|
||||
|
||||
class TestInternetASTopology:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
cls.n = 1000
|
||||
cls.seed = 42
|
||||
cls.G = random_internet_as_graph(cls.n, cls.seed)
|
||||
cls.T = []
|
||||
cls.M = []
|
||||
cls.C = []
|
||||
cls.CP = []
|
||||
cls.customers = {}
|
||||
cls.providers = {}
|
||||
|
||||
for i in cls.G.nodes():
|
||||
if cls.G.nodes[i]["type"] == "T":
|
||||
cls.T.append(i)
|
||||
elif cls.G.nodes[i]["type"] == "M":
|
||||
cls.M.append(i)
|
||||
elif cls.G.nodes[i]["type"] == "C":
|
||||
cls.C.append(i)
|
||||
elif cls.G.nodes[i]["type"] == "CP":
|
||||
cls.CP.append(i)
|
||||
else:
|
||||
raise ValueError(
|
||||
"Inconsistent data in the graph\
|
||||
node attributes"
|
||||
)
|
||||
cls.set_customers(i)
|
||||
cls.set_providers(i)
|
||||
|
||||
@classmethod
|
||||
def set_customers(cls, i):
|
||||
if i not in cls.customers:
|
||||
cls.customers[i] = set()
|
||||
for j in neighbors(cls.G, i):
|
||||
e = cls.G.edges[(i, j)]
|
||||
if e["type"] == "transit":
|
||||
customer = int(e["customer"])
|
||||
if j == customer:
|
||||
cls.set_customers(j)
|
||||
cls.customers[i] = cls.customers[i].union(cls.customers[j])
|
||||
cls.customers[i].add(j)
|
||||
elif i != customer:
|
||||
raise ValueError(
|
||||
"Inconsistent data in the graph\
|
||||
edge attributes"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def set_providers(cls, i):
|
||||
if i not in cls.providers:
|
||||
cls.providers[i] = set()
|
||||
for j in neighbors(cls.G, i):
|
||||
e = cls.G.edges[(i, j)]
|
||||
if e["type"] == "transit":
|
||||
customer = int(e["customer"])
|
||||
if i == customer:
|
||||
cls.set_providers(j)
|
||||
cls.providers[i] = cls.providers[i].union(cls.providers[j])
|
||||
cls.providers[i].add(j)
|
||||
elif j != customer:
|
||||
raise ValueError(
|
||||
"Inconsistent data in the graph\
|
||||
edge attributes"
|
||||
)
|
||||
|
||||
def test_wrong_input(self):
|
||||
G = random_internet_as_graph(0)
|
||||
assert len(G.nodes()) == 0
|
||||
|
||||
G = random_internet_as_graph(-1)
|
||||
assert len(G.nodes()) == 0
|
||||
|
||||
G = random_internet_as_graph(1)
|
||||
assert len(G.nodes()) == 1
|
||||
|
||||
def test_node_numbers(self):
|
||||
assert len(self.G.nodes()) == self.n
|
||||
assert len(self.T) < 7
|
||||
assert len(self.M) == int(round(self.n * 0.15))
|
||||
assert len(self.CP) == int(round(self.n * 0.05))
|
||||
numb = self.n - len(self.T) - len(self.M) - len(self.CP)
|
||||
assert len(self.C) == numb
|
||||
|
||||
def test_connectivity(self):
|
||||
assert is_connected(self.G)
|
||||
|
||||
def test_relationships(self):
|
||||
# T nodes are not customers of anyone
|
||||
for i in self.T:
|
||||
assert len(self.providers[i]) == 0
|
||||
|
||||
# C nodes are not providers of anyone
|
||||
for i in self.C:
|
||||
assert len(self.customers[i]) == 0
|
||||
|
||||
# CP nodes are not providers of anyone
|
||||
for i in self.CP:
|
||||
assert len(self.customers[i]) == 0
|
||||
|
||||
# test whether there is a customer-provider loop
|
||||
for i in self.G.nodes():
|
||||
assert len(self.customers[i].intersection(self.providers[i])) == 0
|
||||
|
||||
# test whether there is a peering with a customer or provider
|
||||
for i, j in self.G.edges():
|
||||
if self.G.edges[(i, j)]["type"] == "peer":
|
||||
assert j not in self.customers[i]
|
||||
assert i not in self.customers[j]
|
||||
assert j not in self.providers[i]
|
||||
assert i not in self.providers[j]
|
||||
|
||||
def test_degree_values(self):
|
||||
d_m = 0 # multihoming degree for M nodes
|
||||
d_cp = 0 # multihoming degree for CP nodes
|
||||
d_c = 0 # multihoming degree for C nodes
|
||||
p_m_m = 0 # avg number of peering edges between M and M
|
||||
p_cp_m = 0 # avg number of peering edges between CP and M
|
||||
p_cp_cp = 0 # avg number of peering edges between CP and CP
|
||||
t_m = 0 # probability M's provider is T
|
||||
t_cp = 0 # probability CP's provider is T
|
||||
t_c = 0 # probability C's provider is T
|
||||
|
||||
for i, j in self.G.edges():
|
||||
e = self.G.edges[(i, j)]
|
||||
if e["type"] == "transit":
|
||||
cust = int(e["customer"])
|
||||
if i == cust:
|
||||
prov = j
|
||||
elif j == cust:
|
||||
prov = i
|
||||
else:
|
||||
raise ValueError(
|
||||
"Inconsistent data in the graph edge\
|
||||
attributes"
|
||||
)
|
||||
if cust in self.M:
|
||||
d_m += 1
|
||||
if self.G.nodes[prov]["type"] == "T":
|
||||
t_m += 1
|
||||
elif cust in self.C:
|
||||
d_c += 1
|
||||
if self.G.nodes[prov]["type"] == "T":
|
||||
t_c += 1
|
||||
elif cust in self.CP:
|
||||
d_cp += 1
|
||||
if self.G.nodes[prov]["type"] == "T":
|
||||
t_cp += 1
|
||||
else:
|
||||
raise ValueError(
|
||||
"Inconsistent data in the graph edge\
|
||||
attributes"
|
||||
)
|
||||
elif e["type"] == "peer":
|
||||
if self.G.nodes[i]["type"] == "M" and self.G.nodes[j]["type"] == "M":
|
||||
p_m_m += 1
|
||||
if self.G.nodes[i]["type"] == "CP" and self.G.nodes[j]["type"] == "CP":
|
||||
p_cp_cp += 1
|
||||
if (
|
||||
self.G.nodes[i]["type"] == "M"
|
||||
and self.G.nodes[j]["type"] == "CP"
|
||||
or self.G.nodes[i]["type"] == "CP"
|
||||
and self.G.nodes[j]["type"] == "M"
|
||||
):
|
||||
p_cp_m += 1
|
||||
else:
|
||||
raise ValueError(
|
||||
"Unexpected data in the graph edge\
|
||||
attributes"
|
||||
)
|
||||
|
||||
assert almost_equal(d_m / len(self.M), 2 + (2.5 * self.n) / 10000, places=0)
|
||||
assert almost_equal(d_cp / len(self.CP), 2 + (1.5 * self.n) / 10000, places=0)
|
||||
assert almost_equal(d_c / len(self.C), 1 + (5 * self.n) / 100000, places=0)
|
||||
|
||||
assert almost_equal(p_m_m / len(self.M), 1 + (2 * self.n) / 10000, places=0)
|
||||
assert almost_equal(p_cp_m / len(self.CP), 0.2 + (2 * self.n) / 10000, places=0)
|
||||
assert almost_equal(
|
||||
p_cp_cp / len(self.CP), 0.05 + (2 * self.n) / 100000, places=0
|
||||
)
|
||||
|
||||
assert almost_equal(t_m / d_m, 0.375, places=1)
|
||||
assert almost_equal(t_cp / d_cp, 0.375, places=1)
|
||||
assert almost_equal(t_c / d_c, 0.125, places=1)
|
|
@ -0,0 +1,27 @@
|
|||
import pytest
|
||||
import networkx as nx
|
||||
|
||||
|
||||
class TestIntersectionGraph:
|
||||
def test_random_intersection_graph(self):
|
||||
G = nx.uniform_random_intersection_graph(10, 5, 0.5)
|
||||
assert len(G) == 10
|
||||
|
||||
def test_k_random_intersection_graph(self):
|
||||
G = nx.k_random_intersection_graph(10, 5, 2)
|
||||
assert len(G) == 10
|
||||
|
||||
def test_k_random_intersection_graph_seeded(self):
|
||||
G = nx.k_random_intersection_graph(10, 5, 2, seed=1234)
|
||||
assert len(G) == 10
|
||||
|
||||
def test_general_random_intersection_graph(self):
|
||||
G = nx.general_random_intersection_graph(10, 5, [0.1, 0.2, 0.2, 0.1, 0.1])
|
||||
assert len(G) == 10
|
||||
pytest.raises(
|
||||
ValueError,
|
||||
nx.general_random_intersection_graph,
|
||||
10,
|
||||
5,
|
||||
[0.1, 0.2, 0.2, 0.1],
|
||||
)
|
|
@ -0,0 +1,144 @@
|
|||
"""Unit tests for the :mod:`networkx.generators.interval_graph` module.
|
||||
|
||||
"""
|
||||
import math
|
||||
import pytest
|
||||
|
||||
import networkx as nx
|
||||
from networkx.generators.interval_graph import interval_graph
|
||||
from networkx.testing import assert_edges_equal
|
||||
|
||||
|
||||
class TestIntervalGraph:
|
||||
"""Unit tests for :func:`networkx.generators.interval_graph.interval_graph`"""
|
||||
|
||||
def test_empty(self):
|
||||
""" Tests for trivial case of empty input"""
|
||||
assert len(interval_graph([])) == 0
|
||||
|
||||
def test_interval_graph_check_invalid(self):
|
||||
""" Tests for conditions that raise Exceptions """
|
||||
|
||||
invalids_having_none = [None, (1, 2)]
|
||||
with pytest.raises(TypeError):
|
||||
interval_graph(invalids_having_none)
|
||||
|
||||
invalids_having_set = [{1, 2}]
|
||||
with pytest.raises(TypeError):
|
||||
interval_graph(invalids_having_set)
|
||||
|
||||
invalids_having_seq_but_not_length2 = [(1, 2, 3)]
|
||||
with pytest.raises(TypeError):
|
||||
interval_graph(invalids_having_seq_but_not_length2)
|
||||
|
||||
invalids_interval = [[3, 2]]
|
||||
with pytest.raises(ValueError):
|
||||
interval_graph(invalids_interval)
|
||||
|
||||
def test_interval_graph_0(self):
|
||||
intervals = [(1, 2), (1, 3)]
|
||||
|
||||
expected_graph = nx.Graph()
|
||||
expected_graph.add_edge(*intervals)
|
||||
|
||||
actual_g = interval_graph(intervals)
|
||||
|
||||
assert set(actual_g.nodes) == set(expected_graph.nodes)
|
||||
assert_edges_equal(expected_graph, actual_g)
|
||||
|
||||
def test_interval_graph_1(self):
|
||||
intervals = [(1, 2), (2, 3), (3, 4), (1, 4)]
|
||||
|
||||
expected_graph = nx.Graph()
|
||||
expected_graph.add_nodes_from(intervals)
|
||||
e1 = ((1, 4), (1, 2))
|
||||
e2 = ((1, 4), (2, 3))
|
||||
e3 = ((1, 4), (3, 4))
|
||||
e4 = ((3, 4), (2, 3))
|
||||
e5 = ((1, 2), (2, 3))
|
||||
|
||||
expected_graph.add_edges_from([e1, e2, e3, e4, e5])
|
||||
|
||||
actual_g = interval_graph(intervals)
|
||||
|
||||
assert set(actual_g.nodes) == set(expected_graph.nodes)
|
||||
assert_edges_equal(expected_graph, actual_g)
|
||||
|
||||
def test_interval_graph_2(self):
|
||||
intervals = [(1, 2), [3, 5], [6, 8], (9, 10)]
|
||||
|
||||
expected_graph = nx.Graph()
|
||||
expected_graph.add_nodes_from([(1, 2), (3, 5), (6, 8), (9, 10)])
|
||||
|
||||
actual_g = interval_graph(intervals)
|
||||
|
||||
assert set(actual_g.nodes) == set(expected_graph.nodes)
|
||||
assert_edges_equal(expected_graph, actual_g)
|
||||
|
||||
def test_interval_graph_3(self):
|
||||
intervals = [(1, 4), [3, 5], [2.5, 4]]
|
||||
|
||||
expected_graph = nx.Graph()
|
||||
expected_graph.add_nodes_from([(1, 4), (3, 5), (2.5, 4)])
|
||||
e1 = ((1, 4), (3, 5))
|
||||
e2 = ((1, 4), (2.5, 4))
|
||||
e3 = ((3, 5), (2.5, 4))
|
||||
|
||||
expected_graph.add_edges_from([e1, e2, e3])
|
||||
|
||||
actual_g = interval_graph(intervals)
|
||||
|
||||
assert set(actual_g.nodes) == set(expected_graph.nodes)
|
||||
assert_edges_equal(expected_graph, actual_g)
|
||||
|
||||
def test_interval_graph_4(self):
|
||||
""" test all possible overlaps """
|
||||
intervals = [
|
||||
(0, 2),
|
||||
(-2, -1),
|
||||
(-2, 0),
|
||||
(-2, 1),
|
||||
(-2, 2),
|
||||
(-2, 3),
|
||||
(0, 1),
|
||||
(0, 2),
|
||||
(0, 3),
|
||||
(1, 2),
|
||||
(1, 3),
|
||||
(2, 3),
|
||||
(3, 4),
|
||||
]
|
||||
|
||||
expected_graph = nx.Graph()
|
||||
expected_graph.add_nodes_from(intervals)
|
||||
expected_nbrs = {
|
||||
(-2, 0),
|
||||
(-2, 1),
|
||||
(-2, 2),
|
||||
(-2, 3),
|
||||
(0, 1),
|
||||
(0, 2),
|
||||
(0, 3),
|
||||
(1, 2),
|
||||
(1, 3),
|
||||
(2, 3),
|
||||
}
|
||||
actual_g = nx.interval_graph(intervals)
|
||||
actual_nbrs = nx.neighbors(actual_g, (0, 2))
|
||||
|
||||
assert set(actual_nbrs) == expected_nbrs
|
||||
|
||||
def test_interval_graph_5(self):
|
||||
""" this test is to see that an interval supports infinite number"""
|
||||
intervals = {(-math.inf, 0), (-1, -1), (0.5, 0.5), (1, 1), (1, math.inf)}
|
||||
|
||||
expected_graph = nx.Graph()
|
||||
expected_graph.add_nodes_from(intervals)
|
||||
e1 = ((-math.inf, 0), (-1, -1))
|
||||
e2 = ((1, 1), (1, math.inf))
|
||||
|
||||
expected_graph.add_edges_from([e1, e2])
|
||||
actual_g = interval_graph(intervals)
|
||||
|
||||
assert set(actual_g.nodes) == set(expected_graph.nodes)
|
||||
assert_edges_equal(expected_graph, actual_g)
|
|
@ -0,0 +1,126 @@
|
|||
import time
|
||||
from networkx.algorithms.assortativity import degree_mixing_dict
|
||||
from networkx.generators import powerlaw_cluster_graph, gnm_random_graph
|
||||
from networkx.generators.joint_degree_seq import (
|
||||
is_valid_joint_degree,
|
||||
joint_degree_graph,
|
||||
directed_joint_degree_graph,
|
||||
is_valid_directed_joint_degree,
|
||||
)
|
||||
|
||||
|
||||
def test_is_valid_joint_degree():
|
||||
""" Tests for conditions that invalidate a joint degree dict """
|
||||
|
||||
# valid joint degree that satisfies all five conditions
|
||||
joint_degrees = {
|
||||
1: {4: 1},
|
||||
2: {2: 2, 3: 2, 4: 2},
|
||||
3: {2: 2, 4: 1},
|
||||
4: {1: 1, 2: 2, 3: 1},
|
||||
}
|
||||
assert is_valid_joint_degree(joint_degrees)
|
||||
|
||||
# test condition 1
|
||||
# joint_degrees_1[1][4] not integer
|
||||
joint_degrees_1 = {
|
||||
1: {4: 1.5},
|
||||
2: {2: 2, 3: 2, 4: 2},
|
||||
3: {2: 2, 4: 1},
|
||||
4: {1: 1.5, 2: 2, 3: 1},
|
||||
}
|
||||
assert not is_valid_joint_degree(joint_degrees_1)
|
||||
|
||||
# test condition 2
|
||||
# degree_count[2] = sum(joint_degrees_2[2][j)/2, is not an int
|
||||
# degree_count[4] = sum(joint_degrees_2[4][j)/4, is not an int
|
||||
joint_degrees_2 = {
|
||||
1: {4: 1},
|
||||
2: {2: 2, 3: 2, 4: 3},
|
||||
3: {2: 2, 4: 1},
|
||||
4: {1: 1, 2: 3, 3: 1},
|
||||
}
|
||||
assert not is_valid_joint_degree(joint_degrees_2)
|
||||
|
||||
# test conditions 3 and 4
|
||||
# joint_degrees_3[1][4]>degree_count[1]*degree_count[4]
|
||||
joint_degrees_3 = {
|
||||
1: {4: 2},
|
||||
2: {2: 2, 3: 2, 4: 2},
|
||||
3: {2: 2, 4: 1},
|
||||
4: {1: 2, 2: 2, 3: 1},
|
||||
}
|
||||
assert not is_valid_joint_degree(joint_degrees_3)
|
||||
|
||||
# test condition 5
|
||||
# joint_degrees_5[1][1] not even
|
||||
joint_degrees_5 = {1: {1: 9}}
|
||||
assert not is_valid_joint_degree(joint_degrees_5)
|
||||
|
||||
|
||||
def test_joint_degree_graph(ntimes=10):
|
||||
for _ in range(ntimes):
|
||||
seed = int(time.time())
|
||||
|
||||
n, m, p = 20, 10, 1
|
||||
# generate random graph with model powerlaw_cluster and calculate
|
||||
# its joint degree
|
||||
g = powerlaw_cluster_graph(n, m, p, seed=seed)
|
||||
joint_degrees_g = degree_mixing_dict(g, normalized=False)
|
||||
|
||||
# generate simple undirected graph with given joint degree
|
||||
# joint_degrees_g
|
||||
G = joint_degree_graph(joint_degrees_g)
|
||||
joint_degrees_G = degree_mixing_dict(G, normalized=False)
|
||||
|
||||
# assert that the given joint degree is equal to the generated
|
||||
# graph's joint degree
|
||||
assert joint_degrees_g == joint_degrees_G
|
||||
|
||||
|
||||
def test_is_valid_directed_joint_degree():
|
||||
|
||||
in_degrees = [0, 1, 1, 2]
|
||||
out_degrees = [1, 1, 1, 1]
|
||||
nkk = {1: {1: 2, 2: 2}}
|
||||
assert is_valid_directed_joint_degree(in_degrees, out_degrees, nkk)
|
||||
|
||||
# not realizable, values are not integers.
|
||||
nkk = {1: {1: 1.5, 2: 2.5}}
|
||||
assert not is_valid_directed_joint_degree(in_degrees, out_degrees, nkk)
|
||||
|
||||
# not realizable, number of edges between 1-2 are insufficient.
|
||||
nkk = {1: {1: 2, 2: 1}}
|
||||
assert not is_valid_directed_joint_degree(in_degrees, out_degrees, nkk)
|
||||
|
||||
# not realizable, in/out degree sequences have different number of nodes.
|
||||
out_degrees = [1, 1, 1]
|
||||
nkk = {1: {1: 2, 2: 2}}
|
||||
assert not is_valid_directed_joint_degree(in_degrees, out_degrees, nkk)
|
||||
|
||||
# not realizable, degree seqeunces have fewer than required nodes.
|
||||
in_degrees = [0, 1, 2]
|
||||
assert not is_valid_directed_joint_degree(in_degrees, out_degrees, nkk)
|
||||
|
||||
|
||||
def test_directed_joint_degree_graph(n=15, m=100, ntimes=1000):
|
||||
for _ in range(ntimes):
|
||||
|
||||
# generate gnm random graph and calculate its joint degree.
|
||||
g = gnm_random_graph(n, m, None, directed=True)
|
||||
|
||||
# in-degree seqeunce of g as a list of integers.
|
||||
in_degrees = list(dict(g.in_degree()).values())
|
||||
# out-degree sequence of g as a list of integers.
|
||||
out_degrees = list(dict(g.out_degree()).values())
|
||||
nkk = degree_mixing_dict(g)
|
||||
|
||||
# generate simple directed graph with given degree sequence and joint
|
||||
# degree matrix.
|
||||
G = directed_joint_degree_graph(in_degrees, out_degrees, nkk)
|
||||
|
||||
# assert degree sequence correctness.
|
||||
assert in_degrees == list(dict(G.in_degree()).values())
|
||||
assert out_degrees == list(dict(G.out_degree()).values())
|
||||
# assert joint degree matrix correctness.
|
||||
assert nkk == degree_mixing_dict(G)
|
239
venv/Lib/site-packages/networkx/generators/tests/test_lattice.py
Normal file
239
venv/Lib/site-packages/networkx/generators/tests/test_lattice.py
Normal file
|
@ -0,0 +1,239 @@
|
|||
"""Unit tests for the :mod:`networkx.generators.lattice` module."""
|
||||
|
||||
import pytest
|
||||
|
||||
import networkx as nx
|
||||
from networkx.testing import assert_edges_equal
|
||||
from itertools import product
|
||||
|
||||
|
||||
class TestGrid2DGraph:
|
||||
"""Unit tests for :func:`networkx.generators.lattice.grid_2d_graph`"""
|
||||
|
||||
def test_number_of_vertices(self):
|
||||
m, n = 5, 6
|
||||
G = nx.grid_2d_graph(m, n)
|
||||
assert len(G) == m * n
|
||||
|
||||
def test_degree_distribution(self):
|
||||
m, n = 5, 6
|
||||
G = nx.grid_2d_graph(m, n)
|
||||
expected_histogram = [0, 0, 4, 2 * (m + n) - 8, (m - 2) * (n - 2)]
|
||||
assert nx.degree_histogram(G) == expected_histogram
|
||||
|
||||
def test_directed(self):
|
||||
m, n = 5, 6
|
||||
G = nx.grid_2d_graph(m, n)
|
||||
H = nx.grid_2d_graph(m, n, create_using=nx.DiGraph())
|
||||
assert H.succ == G.adj
|
||||
assert H.pred == G.adj
|
||||
|
||||
def test_multigraph(self):
|
||||
m, n = 5, 6
|
||||
G = nx.grid_2d_graph(m, n)
|
||||
H = nx.grid_2d_graph(m, n, create_using=nx.MultiGraph())
|
||||
assert list(H.edges()) == list(G.edges())
|
||||
|
||||
def test_periodic(self):
|
||||
G = nx.grid_2d_graph(0, 0, periodic=True)
|
||||
assert dict(G.degree()) == {}
|
||||
|
||||
for m, n, H in [
|
||||
(2, 2, nx.cycle_graph(4)),
|
||||
(1, 7, nx.cycle_graph(7)),
|
||||
(7, 1, nx.cycle_graph(7)),
|
||||
(2, 5, nx.circular_ladder_graph(5)),
|
||||
(5, 2, nx.circular_ladder_graph(5)),
|
||||
(2, 4, nx.cubical_graph()),
|
||||
(4, 2, nx.cubical_graph()),
|
||||
]:
|
||||
G = nx.grid_2d_graph(m, n, periodic=True)
|
||||
assert nx.could_be_isomorphic(G, H)
|
||||
|
||||
def test_periodic_iterable(self):
|
||||
m, n = 3, 7
|
||||
for a, b in product([0, 1], [0, 1]):
|
||||
G = nx.grid_2d_graph(m, n, periodic=(a, b))
|
||||
assert G.number_of_nodes() == m * n
|
||||
assert G.number_of_edges() == (m + a - 1) * n + (n + b - 1) * m
|
||||
|
||||
def test_periodic_directed(self):
|
||||
G = nx.grid_2d_graph(4, 2, periodic=True)
|
||||
H = nx.grid_2d_graph(4, 2, periodic=True, create_using=nx.DiGraph())
|
||||
assert H.succ == G.adj
|
||||
assert H.pred == G.adj
|
||||
|
||||
def test_periodic_multigraph(self):
|
||||
G = nx.grid_2d_graph(4, 2, periodic=True)
|
||||
H = nx.grid_2d_graph(4, 2, periodic=True, create_using=nx.MultiGraph())
|
||||
assert list(G.edges()) == list(H.edges())
|
||||
|
||||
def test_node_input(self):
|
||||
G = nx.grid_2d_graph(4, 2, periodic=True)
|
||||
H = nx.grid_2d_graph(range(4), range(2), periodic=True)
|
||||
assert nx.is_isomorphic(H, G)
|
||||
H = nx.grid_2d_graph("abcd", "ef", periodic=True)
|
||||
assert nx.is_isomorphic(H, G)
|
||||
G = nx.grid_2d_graph(5, 6)
|
||||
H = nx.grid_2d_graph(range(5), range(6))
|
||||
assert_edges_equal(H, G)
|
||||
|
||||
|
||||
class TestGridGraph:
|
||||
"""Unit tests for :func:`networkx.generators.lattice.grid_graph`"""
|
||||
|
||||
def test_grid_graph(self):
|
||||
"""grid_graph([n,m]) is a connected simple graph with the
|
||||
following properties:
|
||||
number_of_nodes = n*m
|
||||
degree_histogram = [0,0,4,2*(n+m)-8,(n-2)*(m-2)]
|
||||
"""
|
||||
for n, m in [(3, 5), (5, 3), (4, 5), (5, 4)]:
|
||||
dim = [n, m]
|
||||
g = nx.grid_graph(dim)
|
||||
assert len(g) == n * m
|
||||
assert nx.degree_histogram(g) == [
|
||||
0,
|
||||
0,
|
||||
4,
|
||||
2 * (n + m) - 8,
|
||||
(n - 2) * (m - 2),
|
||||
]
|
||||
|
||||
for n, m in [(1, 5), (5, 1)]:
|
||||
dim = [n, m]
|
||||
g = nx.grid_graph(dim)
|
||||
assert len(g) == n * m
|
||||
assert nx.is_isomorphic(g, nx.path_graph(5))
|
||||
|
||||
# mg = nx.grid_graph([n,m], create_using=MultiGraph())
|
||||
# assert_equal(mg.edges(), g.edges())
|
||||
|
||||
def test_node_input(self):
|
||||
G = nx.grid_graph([range(7, 9), range(3, 6)])
|
||||
assert len(G) == 2 * 3
|
||||
assert nx.is_isomorphic(G, nx.grid_graph([2, 3]))
|
||||
|
||||
def test_periodic_iterable(self):
|
||||
m, n, k = 3, 7, 5
|
||||
for a, b, c in product([0, 1], [0, 1], [0, 1]):
|
||||
G = nx.grid_graph([m, n, k], periodic=(a, b, c))
|
||||
num_e = (m + a - 1) * n * k + (n + b - 1) * m * k + (k + c - 1) * m * n
|
||||
assert G.number_of_nodes() == m * n * k
|
||||
assert G.number_of_edges() == num_e
|
||||
|
||||
|
||||
class TestHypercubeGraph:
|
||||
"""Unit tests for :func:`networkx.generators.lattice.hypercube_graph`"""
|
||||
|
||||
def test_special_cases(self):
|
||||
for n, H in [
|
||||
(0, nx.null_graph()),
|
||||
(1, nx.path_graph(2)),
|
||||
(2, nx.cycle_graph(4)),
|
||||
(3, nx.cubical_graph()),
|
||||
]:
|
||||
G = nx.hypercube_graph(n)
|
||||
assert nx.could_be_isomorphic(G, H)
|
||||
|
||||
def test_degree_distribution(self):
|
||||
for n in range(1, 10):
|
||||
G = nx.hypercube_graph(n)
|
||||
expected_histogram = [0] * n + [2 ** n]
|
||||
assert nx.degree_histogram(G) == expected_histogram
|
||||
|
||||
|
||||
class TestTriangularLatticeGraph:
|
||||
"Tests for :func:`networkx.generators.lattice.triangular_lattice_graph`"
|
||||
|
||||
def test_lattice_points(self):
|
||||
"""Tests that the graph is really a triangular lattice."""
|
||||
for m, n in [(2, 3), (2, 2), (2, 1), (3, 3), (3, 2), (3, 4)]:
|
||||
G = nx.triangular_lattice_graph(m, n)
|
||||
N = (n + 1) // 2
|
||||
assert len(G) == (m + 1) * (1 + N) - (n % 2) * ((m + 1) // 2)
|
||||
for (i, j) in G.nodes():
|
||||
nbrs = G[(i, j)]
|
||||
if i < N:
|
||||
assert (i + 1, j) in nbrs
|
||||
if j < m:
|
||||
assert (i, j + 1) in nbrs
|
||||
if j < m and (i > 0 or j % 2) and (i < N or (j + 1) % 2):
|
||||
assert (i + 1, j + 1) in nbrs or (i - 1, j + 1) in nbrs
|
||||
|
||||
def test_directed(self):
|
||||
"""Tests for creating a directed triangular lattice."""
|
||||
G = nx.triangular_lattice_graph(3, 4, create_using=nx.Graph())
|
||||
H = nx.triangular_lattice_graph(3, 4, create_using=nx.DiGraph())
|
||||
assert H.is_directed()
|
||||
for u, v in H.edges():
|
||||
assert v[1] >= u[1]
|
||||
if v[1] == u[1]:
|
||||
assert v[0] > u[0]
|
||||
|
||||
def test_multigraph(self):
|
||||
"""Tests for creating a triangular lattice multigraph."""
|
||||
G = nx.triangular_lattice_graph(3, 4, create_using=nx.Graph())
|
||||
H = nx.triangular_lattice_graph(3, 4, create_using=nx.MultiGraph())
|
||||
assert list(H.edges()) == list(G.edges())
|
||||
|
||||
def test_periodic(self):
|
||||
G = nx.triangular_lattice_graph(4, 6, periodic=True)
|
||||
assert len(G) == 12
|
||||
assert G.size() == 36
|
||||
# all degrees are 6
|
||||
assert len([n for n, d in G.degree() if d != 6]) == 0
|
||||
G = nx.triangular_lattice_graph(5, 7, periodic=True)
|
||||
TLG = nx.triangular_lattice_graph
|
||||
pytest.raises(nx.NetworkXError, TLG, 2, 4, periodic=True)
|
||||
pytest.raises(nx.NetworkXError, TLG, 4, 4, periodic=True)
|
||||
pytest.raises(nx.NetworkXError, TLG, 2, 6, periodic=True)
|
||||
|
||||
|
||||
class TestHexagonalLatticeGraph:
|
||||
"Tests for :func:`networkx.generators.lattice.hexagonal_lattice_graph`"
|
||||
|
||||
def test_lattice_points(self):
|
||||
"""Tests that the graph is really a hexagonal lattice."""
|
||||
for m, n in [(4, 5), (4, 4), (4, 3), (3, 2), (3, 3), (3, 5)]:
|
||||
G = nx.hexagonal_lattice_graph(m, n)
|
||||
assert len(G) == 2 * (m + 1) * (n + 1) - 2
|
||||
C_6 = nx.cycle_graph(6)
|
||||
hexagons = [
|
||||
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)],
|
||||
[(0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4)],
|
||||
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3)],
|
||||
[(2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2)],
|
||||
[(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4)],
|
||||
]
|
||||
for hexagon in hexagons:
|
||||
assert nx.is_isomorphic(G.subgraph(hexagon), C_6)
|
||||
|
||||
def test_directed(self):
|
||||
"""Tests for creating a directed hexagonal lattice."""
|
||||
G = nx.hexagonal_lattice_graph(3, 5, create_using=nx.Graph())
|
||||
H = nx.hexagonal_lattice_graph(3, 5, create_using=nx.DiGraph())
|
||||
assert H.is_directed()
|
||||
pos = nx.get_node_attributes(H, "pos")
|
||||
for u, v in H.edges():
|
||||
assert pos[v][1] >= pos[u][1]
|
||||
if pos[v][1] == pos[u][1]:
|
||||
assert pos[v][0] > pos[u][0]
|
||||
|
||||
def test_multigraph(self):
|
||||
"""Tests for creating a hexagonal lattice multigraph."""
|
||||
G = nx.hexagonal_lattice_graph(3, 5, create_using=nx.Graph())
|
||||
H = nx.hexagonal_lattice_graph(3, 5, create_using=nx.MultiGraph())
|
||||
assert list(H.edges()) == list(G.edges())
|
||||
|
||||
def test_periodic(self):
|
||||
G = nx.hexagonal_lattice_graph(4, 6, periodic=True)
|
||||
assert len(G) == 48
|
||||
assert G.size() == 72
|
||||
# all degrees are 3
|
||||
assert len([n for n, d in G.degree() if d != 3]) == 0
|
||||
G = nx.hexagonal_lattice_graph(5, 8, periodic=True)
|
||||
HLG = nx.hexagonal_lattice_graph
|
||||
pytest.raises(nx.NetworkXError, HLG, 2, 7, periodic=True)
|
||||
pytest.raises(nx.NetworkXError, HLG, 1, 4, periodic=True)
|
||||
pytest.raises(nx.NetworkXError, HLG, 2, 1, periodic=True)
|
274
venv/Lib/site-packages/networkx/generators/tests/test_line.py
Normal file
274
venv/Lib/site-packages/networkx/generators/tests/test_line.py
Normal file
|
@ -0,0 +1,274 @@
|
|||
import networkx as nx
|
||||
import pytest
|
||||
|
||||
import networkx.generators.line as line
|
||||
from networkx.testing.utils import assert_edges_equal
|
||||
|
||||
|
||||
def test_node_func():
|
||||
# graph
|
||||
G = nx.Graph()
|
||||
G.add_edge(1, 2)
|
||||
nf = line._node_func(G)
|
||||
assert nf(1, 2) == (1, 2)
|
||||
assert nf(2, 1) == (1, 2)
|
||||
|
||||
# multigraph
|
||||
G = nx.MultiGraph()
|
||||
G.add_edge(1, 2)
|
||||
G.add_edge(1, 2)
|
||||
nf = line._node_func(G)
|
||||
assert nf(1, 2, 0) == (1, 2, 0)
|
||||
assert nf(2, 1, 0) == (1, 2, 0)
|
||||
|
||||
|
||||
def test_edge_func():
|
||||
# graph
|
||||
G = nx.Graph()
|
||||
G.add_edge(1, 2)
|
||||
G.add_edge(2, 3)
|
||||
ef = line._edge_func(G)
|
||||
expected = [(1, 2), (2, 3)]
|
||||
assert_edges_equal(ef(), expected)
|
||||
|
||||
# digraph
|
||||
G = nx.MultiDiGraph()
|
||||
G.add_edge(1, 2)
|
||||
G.add_edge(2, 3)
|
||||
G.add_edge(2, 3)
|
||||
ef = line._edge_func(G)
|
||||
expected = [(1, 2, 0), (2, 3, 0), (2, 3, 1)]
|
||||
result = sorted(ef())
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_sorted_edge():
|
||||
assert (1, 2) == line._sorted_edge(1, 2)
|
||||
assert (1, 2) == line._sorted_edge(2, 1)
|
||||
|
||||
|
||||
class TestGeneratorLine:
|
||||
def test_star(self):
|
||||
G = nx.star_graph(5)
|
||||
L = nx.line_graph(G)
|
||||
assert nx.is_isomorphic(L, nx.complete_graph(5))
|
||||
|
||||
def test_path(self):
|
||||
G = nx.path_graph(5)
|
||||
L = nx.line_graph(G)
|
||||
assert nx.is_isomorphic(L, nx.path_graph(4))
|
||||
|
||||
def test_cycle(self):
|
||||
G = nx.cycle_graph(5)
|
||||
L = nx.line_graph(G)
|
||||
assert nx.is_isomorphic(L, G)
|
||||
|
||||
def test_digraph1(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_edges_from([(0, 1), (0, 2), (0, 3)])
|
||||
L = nx.line_graph(G)
|
||||
# no edge graph, but with nodes
|
||||
assert L.adj == {(0, 1): {}, (0, 2): {}, (0, 3): {}}
|
||||
|
||||
def test_digraph2(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_edges_from([(0, 1), (1, 2), (2, 3)])
|
||||
L = nx.line_graph(G)
|
||||
assert_edges_equal(L.edges(), [((0, 1), (1, 2)), ((1, 2), (2, 3))])
|
||||
|
||||
def test_create1(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_edges_from([(0, 1), (1, 2), (2, 3)])
|
||||
L = nx.line_graph(G, create_using=nx.Graph())
|
||||
assert_edges_equal(L.edges(), [((0, 1), (1, 2)), ((1, 2), (2, 3))])
|
||||
|
||||
def test_create2(self):
|
||||
G = nx.Graph()
|
||||
G.add_edges_from([(0, 1), (1, 2), (2, 3)])
|
||||
L = nx.line_graph(G, create_using=nx.DiGraph())
|
||||
assert_edges_equal(L.edges(), [((0, 1), (1, 2)), ((1, 2), (2, 3))])
|
||||
|
||||
|
||||
class TestGeneratorInverseLine:
|
||||
def test_example(self):
|
||||
G = nx.Graph()
|
||||
G_edges = [
|
||||
[1, 2],
|
||||
[1, 3],
|
||||
[1, 4],
|
||||
[1, 5],
|
||||
[2, 3],
|
||||
[2, 5],
|
||||
[2, 6],
|
||||
[2, 7],
|
||||
[3, 4],
|
||||
[3, 5],
|
||||
[6, 7],
|
||||
[6, 8],
|
||||
[7, 8],
|
||||
]
|
||||
G.add_edges_from(G_edges)
|
||||
H = nx.inverse_line_graph(G)
|
||||
solution = nx.Graph()
|
||||
solution_edges = [
|
||||
("a", "b"),
|
||||
("a", "c"),
|
||||
("a", "d"),
|
||||
("a", "e"),
|
||||
("c", "d"),
|
||||
("e", "f"),
|
||||
("e", "g"),
|
||||
("f", "g"),
|
||||
]
|
||||
solution.add_edges_from(solution_edges)
|
||||
assert nx.is_isomorphic(H, solution)
|
||||
|
||||
def test_example_2(self):
|
||||
G = nx.Graph()
|
||||
G_edges = [[1, 2], [1, 3], [2, 3], [3, 4], [3, 5], [4, 5]]
|
||||
G.add_edges_from(G_edges)
|
||||
H = nx.inverse_line_graph(G)
|
||||
solution = nx.Graph()
|
||||
solution_edges = [("a", "c"), ("b", "c"), ("c", "d"), ("d", "e"), ("d", "f")]
|
||||
solution.add_edges_from(solution_edges)
|
||||
assert nx.is_isomorphic(H, solution)
|
||||
|
||||
def test_pair(self):
|
||||
G = nx.path_graph(2)
|
||||
H = nx.inverse_line_graph(G)
|
||||
solution = nx.path_graph(3)
|
||||
assert nx.is_isomorphic(H, solution)
|
||||
|
||||
def test_line(self):
|
||||
G = nx.path_graph(5)
|
||||
solution = nx.path_graph(6)
|
||||
H = nx.inverse_line_graph(G)
|
||||
assert nx.is_isomorphic(H, solution)
|
||||
|
||||
def test_triangle_graph(self):
|
||||
G = nx.complete_graph(3)
|
||||
H = nx.inverse_line_graph(G)
|
||||
alternative_solution = nx.Graph()
|
||||
alternative_solution.add_edges_from([[0, 1], [0, 2], [0, 3]])
|
||||
# there are two alternative inverse line graphs for this case
|
||||
# so long as we get one of them the test should pass
|
||||
assert nx.is_isomorphic(H, G) or nx.is_isomorphic(H, alternative_solution)
|
||||
|
||||
def test_cycle(self):
|
||||
G = nx.cycle_graph(5)
|
||||
H = nx.inverse_line_graph(G)
|
||||
assert nx.is_isomorphic(H, G)
|
||||
|
||||
def test_empty(self):
|
||||
G = nx.Graph()
|
||||
H = nx.inverse_line_graph(G)
|
||||
assert nx.is_isomorphic(H, nx.complete_graph(1))
|
||||
|
||||
def test_K1(self):
|
||||
G = nx.complete_graph(1)
|
||||
H = nx.inverse_line_graph(G)
|
||||
solution = nx.path_graph(2)
|
||||
assert nx.is_isomorphic(H, solution)
|
||||
|
||||
def test_claw(self):
|
||||
# This is the simplest non-line graph
|
||||
G = nx.Graph()
|
||||
G_edges = [[0, 1], [0, 2], [0, 3]]
|
||||
G.add_edges_from(G_edges)
|
||||
pytest.raises(nx.NetworkXError, nx.inverse_line_graph, G)
|
||||
|
||||
def test_non_line_graph(self):
|
||||
# These are other non-line graphs
|
||||
|
||||
# wheel graph with 6 nodes
|
||||
G = nx.Graph()
|
||||
G_edges = [
|
||||
[0, 1],
|
||||
[0, 2],
|
||||
[0, 3],
|
||||
[0, 4],
|
||||
[0, 5],
|
||||
[1, 2],
|
||||
[2, 3],
|
||||
[3, 4],
|
||||
[4, 5],
|
||||
[5, 1],
|
||||
]
|
||||
G.add_edges_from(G_edges)
|
||||
pytest.raises(nx.NetworkXError, nx.inverse_line_graph, G)
|
||||
|
||||
# 3---4---5
|
||||
# / \ / \ /
|
||||
# 0---1---2
|
||||
G = nx.Graph()
|
||||
G_edges = [
|
||||
[0, 1],
|
||||
[1, 2],
|
||||
[3, 4],
|
||||
[4, 5],
|
||||
[0, 3],
|
||||
[1, 3],
|
||||
[1, 4],
|
||||
[2, 4],
|
||||
[2, 5],
|
||||
]
|
||||
G.add_edges_from(G_edges)
|
||||
pytest.raises(nx.NetworkXError, nx.inverse_line_graph, G)
|
||||
|
||||
# K_5 minus an edge
|
||||
K5me = nx.complete_graph(5)
|
||||
K5me.remove_edge(0, 1)
|
||||
pytest.raises(nx.NetworkXError, nx.inverse_line_graph, K5me)
|
||||
|
||||
def test_wrong_graph_type(self):
|
||||
G = nx.DiGraph()
|
||||
G_edges = [[0, 1], [0, 2], [0, 3]]
|
||||
G.add_edges_from(G_edges)
|
||||
pytest.raises(nx.NetworkXNotImplemented, nx.inverse_line_graph, G)
|
||||
|
||||
G = nx.MultiGraph()
|
||||
G_edges = [[0, 1], [0, 2], [0, 3]]
|
||||
G.add_edges_from(G_edges)
|
||||
pytest.raises(nx.NetworkXNotImplemented, nx.inverse_line_graph, G)
|
||||
|
||||
def test_line_inverse_line_complete(self):
|
||||
G = nx.complete_graph(10)
|
||||
H = nx.line_graph(G)
|
||||
J = nx.inverse_line_graph(H)
|
||||
assert nx.is_isomorphic(G, J)
|
||||
|
||||
def test_line_inverse_line_path(self):
|
||||
G = nx.path_graph(10)
|
||||
H = nx.line_graph(G)
|
||||
J = nx.inverse_line_graph(H)
|
||||
assert nx.is_isomorphic(G, J)
|
||||
|
||||
def test_line_inverse_line_hypercube(self):
|
||||
G = nx.hypercube_graph(5)
|
||||
H = nx.line_graph(G)
|
||||
J = nx.inverse_line_graph(H)
|
||||
assert nx.is_isomorphic(G, J)
|
||||
|
||||
def test_line_inverse_line_cycle(self):
|
||||
G = nx.cycle_graph(10)
|
||||
H = nx.line_graph(G)
|
||||
J = nx.inverse_line_graph(H)
|
||||
assert nx.is_isomorphic(G, J)
|
||||
|
||||
def test_line_inverse_line_star(self):
|
||||
G = nx.star_graph(20)
|
||||
H = nx.line_graph(G)
|
||||
J = nx.inverse_line_graph(H)
|
||||
assert nx.is_isomorphic(G, J)
|
||||
|
||||
def test_line_inverse_line_multipartite(self):
|
||||
G = nx.complete_multipartite_graph(3, 4, 5)
|
||||
H = nx.line_graph(G)
|
||||
J = nx.inverse_line_graph(H)
|
||||
assert nx.is_isomorphic(G, J)
|
||||
|
||||
def test_line_inverse_line_dgm(self):
|
||||
G = nx.dorogovtsev_goltsev_mendes_graph(4)
|
||||
H = nx.line_graph(G)
|
||||
J = nx.inverse_line_graph(H)
|
||||
assert nx.is_isomorphic(G, J)
|
|
@ -0,0 +1,26 @@
|
|||
"""Unit tests for the :mod:`networkx.generators.mycielski` module."""
|
||||
|
||||
import networkx as nx
|
||||
|
||||
|
||||
class TestMycielski:
|
||||
def test_construction(self):
|
||||
G = nx.path_graph(2)
|
||||
M = nx.mycielskian(G)
|
||||
assert nx.is_isomorphic(M, nx.cycle_graph(5))
|
||||
|
||||
def test_size(self):
|
||||
G = nx.path_graph(2)
|
||||
M = nx.mycielskian(G, 2)
|
||||
assert len(M) == 11
|
||||
assert M.size() == 20
|
||||
|
||||
def test_mycielski_graph_generator(self):
|
||||
G = nx.mycielski_graph(1)
|
||||
assert nx.is_isomorphic(G, nx.empty_graph(1))
|
||||
G = nx.mycielski_graph(2)
|
||||
assert nx.is_isomorphic(G, nx.path_graph(2))
|
||||
G = nx.mycielski_graph(3)
|
||||
assert nx.is_isomorphic(G, nx.cycle_graph(5))
|
||||
G = nx.mycielski_graph(4)
|
||||
assert nx.is_isomorphic(G, nx.mycielskian(nx.cycle_graph(5)))
|
|
@ -0,0 +1,64 @@
|
|||
"""
|
||||
====================
|
||||
Generators - Non Isomorphic Trees
|
||||
====================
|
||||
|
||||
Unit tests for WROM algorithm generator in generators/nonisomorphic_trees.py
|
||||
"""
|
||||
import networkx as nx
|
||||
from networkx.testing import assert_edges_equal
|
||||
|
||||
|
||||
class TestGeneratorNonIsomorphicTrees:
|
||||
def test_tree_structure(self):
|
||||
# test for tree structure for nx.nonisomorphic_trees()
|
||||
def f(x):
|
||||
return list(nx.nonisomorphic_trees(x))
|
||||
|
||||
for i in f(6):
|
||||
assert nx.is_tree(i)
|
||||
for i in f(8):
|
||||
assert nx.is_tree(i)
|
||||
|
||||
def test_nonisomorphism(self):
|
||||
# test for nonisomorphism of trees for nx.nonisomorphic_trees()
|
||||
def f(x):
|
||||
return list(nx.nonisomorphic_trees(x))
|
||||
|
||||
trees = f(6)
|
||||
for i in range(len(trees)):
|
||||
for j in range(i + 1, len(trees)):
|
||||
assert not nx.is_isomorphic(trees[i], trees[j])
|
||||
trees = f(8)
|
||||
for i in range(len(trees)):
|
||||
for j in range(i + 1, len(trees)):
|
||||
assert not nx.is_isomorphic(trees[i], trees[j])
|
||||
|
||||
def test_number_of_nonisomorphic_trees(self):
|
||||
# http://oeis.org/A000055
|
||||
assert nx.number_of_nonisomorphic_trees(2) == 1
|
||||
assert nx.number_of_nonisomorphic_trees(3) == 1
|
||||
assert nx.number_of_nonisomorphic_trees(4) == 2
|
||||
assert nx.number_of_nonisomorphic_trees(5) == 3
|
||||
assert nx.number_of_nonisomorphic_trees(6) == 6
|
||||
assert nx.number_of_nonisomorphic_trees(7) == 11
|
||||
assert nx.number_of_nonisomorphic_trees(8) == 23
|
||||
|
||||
def test_nonisomorphic_trees(self):
|
||||
def f(x):
|
||||
return list(nx.nonisomorphic_trees(x))
|
||||
|
||||
assert_edges_equal(f(3)[0].edges(), [(0, 1), (0, 2)])
|
||||
assert_edges_equal(f(4)[0].edges(), [(0, 1), (0, 3), (1, 2)])
|
||||
assert_edges_equal(f(4)[1].edges(), [(0, 1), (0, 2), (0, 3)])
|
||||
|
||||
def test_nonisomorphic_trees_matrix(self):
|
||||
trees_2 = [[[0, 1], [1, 0]]]
|
||||
assert list(nx.nonisomorphic_trees(2, create="matrix")) == trees_2
|
||||
trees_3 = [[[0, 1, 1], [1, 0, 0], [1, 0, 0]]]
|
||||
assert list(nx.nonisomorphic_trees(3, create="matrix")) == trees_3
|
||||
trees_4 = [
|
||||
[[0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]],
|
||||
[[0, 1, 1, 1], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]],
|
||||
]
|
||||
assert list(nx.nonisomorphic_trees(4, create="matrix")) == trees_4
|
|
@ -0,0 +1,33 @@
|
|||
import pytest
|
||||
import networkx
|
||||
|
||||
|
||||
class TestRandomClusteredGraph:
|
||||
def test_valid(self):
|
||||
node = [1, 1, 1, 2, 1, 2, 0, 0]
|
||||
tri = [0, 0, 0, 0, 0, 1, 1, 1]
|
||||
joint_degree_sequence = zip(node, tri)
|
||||
G = networkx.random_clustered_graph(joint_degree_sequence)
|
||||
assert G.number_of_nodes() == 8
|
||||
assert G.number_of_edges() == 7
|
||||
|
||||
def test_valid2(self):
|
||||
G = networkx.random_clustered_graph(
|
||||
[(1, 2), (2, 1), (1, 1), (1, 1), (1, 1), (2, 0)]
|
||||
)
|
||||
assert G.number_of_nodes() == 6
|
||||
assert G.number_of_edges() == 10
|
||||
|
||||
def test_invalid1(self):
|
||||
pytest.raises(
|
||||
(TypeError, networkx.NetworkXError),
|
||||
networkx.random_clustered_graph,
|
||||
[[1, 1], [2, 1], [0, 1]],
|
||||
)
|
||||
|
||||
def test_invalid2(self):
|
||||
pytest.raises(
|
||||
(TypeError, networkx.NetworkXError),
|
||||
networkx.random_clustered_graph,
|
||||
[[1, 1], [1, 2], [0, 1]],
|
||||
)
|
|
@ -0,0 +1,300 @@
|
|||
"""Unit tests for the :mod:`networkx.generators.random_graphs` module.
|
||||
|
||||
"""
|
||||
import pytest
|
||||
|
||||
from networkx.exception import NetworkXError
|
||||
from networkx.generators.random_graphs import barabasi_albert_graph
|
||||
from networkx.generators.random_graphs import dual_barabasi_albert_graph
|
||||
from networkx.generators.random_graphs import extended_barabasi_albert_graph
|
||||
from networkx.generators.random_graphs import binomial_graph
|
||||
from networkx.generators.random_graphs import connected_watts_strogatz_graph
|
||||
from networkx.generators.random_graphs import dense_gnm_random_graph
|
||||
from networkx.generators.random_graphs import erdos_renyi_graph
|
||||
from networkx.generators.random_graphs import fast_gnp_random_graph
|
||||
from networkx.generators.random_graphs import gnm_random_graph
|
||||
from networkx.generators.random_graphs import gnp_random_graph
|
||||
from networkx.generators.random_graphs import newman_watts_strogatz_graph
|
||||
from networkx.generators.random_graphs import powerlaw_cluster_graph
|
||||
from networkx.generators.random_graphs import random_kernel_graph
|
||||
from networkx.generators.random_graphs import random_lobster
|
||||
from networkx.generators.random_graphs import random_powerlaw_tree
|
||||
from networkx.generators.random_graphs import random_powerlaw_tree_sequence
|
||||
from networkx.generators.random_graphs import random_regular_graph
|
||||
from networkx.generators.random_graphs import random_shell_graph
|
||||
from networkx.generators.random_graphs import watts_strogatz_graph
|
||||
|
||||
|
||||
class TestGeneratorsRandom:
|
||||
def test_random_graph(self):
|
||||
seed = 42
|
||||
G = gnp_random_graph(100, 0.25, seed)
|
||||
G = gnp_random_graph(100, 0.25, seed, directed=True)
|
||||
G = binomial_graph(100, 0.25, seed)
|
||||
G = erdos_renyi_graph(100, 0.25, seed)
|
||||
G = fast_gnp_random_graph(100, 0.25, seed)
|
||||
G = fast_gnp_random_graph(100, 0.25, seed, directed=True)
|
||||
G = gnm_random_graph(100, 20, seed)
|
||||
G = gnm_random_graph(100, 20, seed, directed=True)
|
||||
G = dense_gnm_random_graph(100, 20, seed)
|
||||
|
||||
G = watts_strogatz_graph(10, 2, 0.25, seed)
|
||||
assert len(G) == 10
|
||||
assert G.number_of_edges() == 10
|
||||
|
||||
G = connected_watts_strogatz_graph(10, 2, 0.1, tries=10, seed=seed)
|
||||
assert len(G) == 10
|
||||
assert G.number_of_edges() == 10
|
||||
pytest.raises(
|
||||
NetworkXError, connected_watts_strogatz_graph, 10, 2, 0.1, tries=0
|
||||
)
|
||||
|
||||
G = watts_strogatz_graph(10, 4, 0.25, seed)
|
||||
assert len(G) == 10
|
||||
assert G.number_of_edges() == 20
|
||||
|
||||
G = newman_watts_strogatz_graph(10, 2, 0.0, seed)
|
||||
assert len(G) == 10
|
||||
assert G.number_of_edges() == 10
|
||||
|
||||
G = newman_watts_strogatz_graph(10, 4, 0.25, seed)
|
||||
assert len(G) == 10
|
||||
assert G.number_of_edges() >= 20
|
||||
|
||||
G = barabasi_albert_graph(100, 1, seed)
|
||||
G = barabasi_albert_graph(100, 3, seed)
|
||||
assert G.number_of_edges() == (97 * 3)
|
||||
|
||||
G = extended_barabasi_albert_graph(100, 1, 0, 0, seed)
|
||||
assert G.number_of_edges() == 99
|
||||
G = extended_barabasi_albert_graph(100, 3, 0, 0, seed)
|
||||
assert G.number_of_edges() == 97 * 3
|
||||
G = extended_barabasi_albert_graph(100, 1, 0, 0.5, seed)
|
||||
assert G.number_of_edges() == 99
|
||||
G = extended_barabasi_albert_graph(100, 2, 0.5, 0, seed)
|
||||
assert G.number_of_edges() > 100 * 3
|
||||
assert G.number_of_edges() < 100 * 4
|
||||
|
||||
G = extended_barabasi_albert_graph(100, 2, 0.3, 0.3, seed)
|
||||
assert G.number_of_edges() > 100 * 2
|
||||
assert G.number_of_edges() < 100 * 4
|
||||
|
||||
G = powerlaw_cluster_graph(100, 1, 1.0, seed)
|
||||
G = powerlaw_cluster_graph(100, 3, 0.0, seed)
|
||||
assert G.number_of_edges() == (97 * 3)
|
||||
|
||||
G = random_regular_graph(10, 20, seed)
|
||||
|
||||
pytest.raises(NetworkXError, random_regular_graph, 3, 21)
|
||||
pytest.raises(NetworkXError, random_regular_graph, 33, 21)
|
||||
|
||||
constructor = [(10, 20, 0.8), (20, 40, 0.8)]
|
||||
G = random_shell_graph(constructor, seed)
|
||||
|
||||
def is_caterpillar(g):
|
||||
"""
|
||||
A tree is a caterpillar iff all nodes of degree >=3 are surrounded
|
||||
by at most two nodes of degree two or greater.
|
||||
ref: http://mathworld.wolfram.com/CaterpillarGraph.html
|
||||
"""
|
||||
deg_over_3 = [n for n in g if g.degree(n) >= 3]
|
||||
for n in deg_over_3:
|
||||
nbh_deg_over_2 = [nbh for nbh in g.neighbors(n) if g.degree(nbh) >= 2]
|
||||
if not len(nbh_deg_over_2) <= 2:
|
||||
return False
|
||||
return True
|
||||
|
||||
def is_lobster(g):
|
||||
"""
|
||||
A tree is a lobster if it has the property that the removal of leaf
|
||||
nodes leaves a caterpillar graph (Gallian 2007)
|
||||
ref: http://mathworld.wolfram.com/LobsterGraph.html
|
||||
"""
|
||||
non_leafs = [n for n in g if g.degree(n) > 1]
|
||||
return is_caterpillar(g.subgraph(non_leafs))
|
||||
|
||||
G = random_lobster(10, 0.1, 0.5, seed)
|
||||
assert max([G.degree(n) for n in G.nodes()]) > 3
|
||||
assert is_lobster(G)
|
||||
pytest.raises(NetworkXError, random_lobster, 10, 0.1, 1, seed)
|
||||
pytest.raises(NetworkXError, random_lobster, 10, 1, 1, seed)
|
||||
pytest.raises(NetworkXError, random_lobster, 10, 1, 0.5, seed)
|
||||
|
||||
# docstring says this should be a caterpillar
|
||||
G = random_lobster(10, 0.1, 0.0, seed)
|
||||
assert is_caterpillar(G)
|
||||
|
||||
# difficult to find seed that requires few tries
|
||||
seq = random_powerlaw_tree_sequence(10, 3, seed=14, tries=1)
|
||||
G = random_powerlaw_tree(10, 3, seed=14, tries=1)
|
||||
|
||||
def test_dual_barabasi_albert(self, m1=1, m2=4, p=0.5):
|
||||
"""
|
||||
Tests that the dual BA random graph generated behaves consistently.
|
||||
|
||||
Tests the exceptions are raised as expected.
|
||||
|
||||
The graphs generation are repeated several times to prevent lucky shots
|
||||
|
||||
"""
|
||||
seed = 42
|
||||
repeats = 2
|
||||
|
||||
while repeats:
|
||||
repeats -= 1
|
||||
|
||||
# This should be BA with m = m1
|
||||
BA1 = barabasi_albert_graph(100, m1, seed)
|
||||
DBA1 = dual_barabasi_albert_graph(100, m1, m2, 1, seed)
|
||||
assert BA1.size() == DBA1.size()
|
||||
|
||||
# This should be BA with m = m2
|
||||
BA2 = barabasi_albert_graph(100, m2, seed)
|
||||
DBA2 = dual_barabasi_albert_graph(100, m1, m2, 0, seed)
|
||||
assert BA2.size() == DBA2.size()
|
||||
|
||||
# Testing exceptions
|
||||
dbag = dual_barabasi_albert_graph
|
||||
pytest.raises(NetworkXError, dbag, m1, m1, m2, 0)
|
||||
pytest.raises(NetworkXError, dbag, m2, m1, m2, 0)
|
||||
pytest.raises(NetworkXError, dbag, 100, m1, m2, -0.5)
|
||||
pytest.raises(NetworkXError, dbag, 100, m1, m2, 1.5)
|
||||
|
||||
def test_extended_barabasi_albert(self, m=2):
|
||||
"""
|
||||
Tests that the extended BA random graph generated behaves consistently.
|
||||
|
||||
Tests the exceptions are raised as expected.
|
||||
|
||||
The graphs generation are repeated several times to prevent lucky-shots
|
||||
|
||||
"""
|
||||
seed = 42
|
||||
repeats = 2
|
||||
BA_model = barabasi_albert_graph(100, m, seed)
|
||||
BA_model_edges = BA_model.number_of_edges()
|
||||
|
||||
while repeats:
|
||||
repeats -= 1
|
||||
|
||||
# This behaves just like BA, the number of edges must be the same
|
||||
G1 = extended_barabasi_albert_graph(100, m, 0, 0, seed)
|
||||
assert G1.size() == BA_model_edges
|
||||
|
||||
# More than twice more edges should have been added
|
||||
G1 = extended_barabasi_albert_graph(100, m, 0.8, 0, seed)
|
||||
assert G1.size() > BA_model_edges * 2
|
||||
|
||||
# Only edge rewiring, so the number of edges less than original
|
||||
G2 = extended_barabasi_albert_graph(100, m, 0, 0.8, seed)
|
||||
assert G2.size() == BA_model_edges
|
||||
|
||||
# Mixed scenario: less edges than G1 and more edges than G2
|
||||
G3 = extended_barabasi_albert_graph(100, m, 0.3, 0.3, seed)
|
||||
assert G3.size() > G2.size()
|
||||
assert G3.size() < G1.size()
|
||||
|
||||
# Testing exceptions
|
||||
ebag = extended_barabasi_albert_graph
|
||||
pytest.raises(NetworkXError, ebag, m, m, 0, 0)
|
||||
pytest.raises(NetworkXError, ebag, 1, 0.5, 0, 0)
|
||||
pytest.raises(NetworkXError, ebag, 100, 2, 0.5, 0.5)
|
||||
|
||||
def test_random_zero_regular_graph(self):
|
||||
"""Tests that a 0-regular graph has the correct number of nodes and
|
||||
edges.
|
||||
|
||||
"""
|
||||
seed = 42
|
||||
G = random_regular_graph(0, 10, seed)
|
||||
assert len(G) == 10
|
||||
assert sum(1 for _ in G.edges()) == 0
|
||||
|
||||
def test_gnp(self):
|
||||
for generator in [
|
||||
gnp_random_graph,
|
||||
binomial_graph,
|
||||
erdos_renyi_graph,
|
||||
fast_gnp_random_graph,
|
||||
]:
|
||||
G = generator(10, -1.1)
|
||||
assert len(G) == 10
|
||||
assert sum(1 for _ in G.edges()) == 0
|
||||
|
||||
G = generator(10, 0.1)
|
||||
assert len(G) == 10
|
||||
|
||||
G = generator(10, 0.1, seed=42)
|
||||
assert len(G) == 10
|
||||
|
||||
G = generator(10, 1.1)
|
||||
assert len(G) == 10
|
||||
assert sum(1 for _ in G.edges()) == 45
|
||||
|
||||
G = generator(10, -1.1, directed=True)
|
||||
assert G.is_directed()
|
||||
assert len(G) == 10
|
||||
assert sum(1 for _ in G.edges()) == 0
|
||||
|
||||
G = generator(10, 0.1, directed=True)
|
||||
assert G.is_directed()
|
||||
assert len(G) == 10
|
||||
|
||||
G = generator(10, 1.1, directed=True)
|
||||
assert G.is_directed()
|
||||
assert len(G) == 10
|
||||
assert sum(1 for _ in G.edges()) == 90
|
||||
|
||||
# assert that random graphs generate all edges for p close to 1
|
||||
edges = 0
|
||||
runs = 100
|
||||
for i in range(runs):
|
||||
edges += sum(1 for _ in generator(10, 0.99999, directed=True).edges())
|
||||
assert abs(edges / float(runs) - 90) <= runs * 2.0 / 100
|
||||
|
||||
def test_gnm(self):
|
||||
G = gnm_random_graph(10, 3)
|
||||
assert len(G) == 10
|
||||
assert sum(1 for _ in G.edges()) == 3
|
||||
|
||||
G = gnm_random_graph(10, 3, seed=42)
|
||||
assert len(G) == 10
|
||||
assert sum(1 for _ in G.edges()) == 3
|
||||
|
||||
G = gnm_random_graph(10, 100)
|
||||
assert len(G) == 10
|
||||
assert sum(1 for _ in G.edges()) == 45
|
||||
|
||||
G = gnm_random_graph(10, 100, directed=True)
|
||||
assert len(G) == 10
|
||||
assert sum(1 for _ in G.edges()) == 90
|
||||
|
||||
G = gnm_random_graph(10, -1.1)
|
||||
assert len(G) == 10
|
||||
assert sum(1 for _ in G.edges()) == 0
|
||||
|
||||
def test_watts_strogatz_big_k(self):
|
||||
# Test to make sure than n <= k
|
||||
pytest.raises(NetworkXError, watts_strogatz_graph, 10, 11, 0.25)
|
||||
pytest.raises(NetworkXError, newman_watts_strogatz_graph, 10, 11, 0.25)
|
||||
|
||||
# could create an infinite loop, now doesn't
|
||||
# infinite loop used to occur when a node has degree n-1 and needs to rewire
|
||||
watts_strogatz_graph(10, 9, 0.25, seed=0)
|
||||
newman_watts_strogatz_graph(10, 9, 0.5, seed=0)
|
||||
|
||||
# Test k==n scenario
|
||||
watts_strogatz_graph(10, 10, 0.25, seed=0)
|
||||
newman_watts_strogatz_graph(10, 10, 0.25, seed=0)
|
||||
|
||||
def test_random_kernel_graph(self):
|
||||
def integral(u, w, z):
|
||||
return c * (z - w)
|
||||
|
||||
def root(u, w, r):
|
||||
return r / c + w
|
||||
|
||||
c = 1
|
||||
graph = random_kernel_graph(1000, integral, root)
|
||||
graph = random_kernel_graph(1000, integral, root, seed=42)
|
||||
assert len(graph) == 1000
|
188
venv/Lib/site-packages/networkx/generators/tests/test_small.py
Normal file
188
venv/Lib/site-packages/networkx/generators/tests/test_small.py
Normal file
|
@ -0,0 +1,188 @@
|
|||
import pytest
|
||||
import networkx as nx
|
||||
from networkx.algorithms.isomorphism.isomorph import graph_could_be_isomorphic
|
||||
|
||||
is_isomorphic = graph_could_be_isomorphic
|
||||
|
||||
"""Generators - Small
|
||||
=====================
|
||||
|
||||
Some small graphs
|
||||
"""
|
||||
|
||||
null = nx.null_graph()
|
||||
|
||||
|
||||
class TestGeneratorsSmall:
|
||||
def test_make_small_graph(self):
|
||||
d = ["adjacencylist", "Bull Graph", 5, [[2, 3], [1, 3, 4], [1, 2, 5], [2], [3]]]
|
||||
G = nx.make_small_graph(d)
|
||||
assert is_isomorphic(G, nx.bull_graph())
|
||||
|
||||
# Test small graph creation error with wrong ltype
|
||||
d[0] = "erroneouslist"
|
||||
pytest.raises(nx.NetworkXError, nx.make_small_graph, graph_description=d)
|
||||
|
||||
def test__LCF_graph(self):
|
||||
# If n<=0, then return the null_graph
|
||||
G = nx.LCF_graph(-10, [1, 2], 100)
|
||||
assert is_isomorphic(G, null)
|
||||
G = nx.LCF_graph(0, [1, 2], 3)
|
||||
assert is_isomorphic(G, null)
|
||||
G = nx.LCF_graph(0, [1, 2], 10)
|
||||
assert is_isomorphic(G, null)
|
||||
|
||||
# Test that LCF(n,[],0) == cycle_graph(n)
|
||||
for a, b, c in [(5, [], 0), (10, [], 0), (5, [], 1), (10, [], 10)]:
|
||||
G = nx.LCF_graph(a, b, c)
|
||||
assert is_isomorphic(G, nx.cycle_graph(a))
|
||||
|
||||
# Generate the utility graph K_{3,3}
|
||||
G = nx.LCF_graph(6, [3, -3], 3)
|
||||
utility_graph = nx.complete_bipartite_graph(3, 3)
|
||||
assert is_isomorphic(G, utility_graph)
|
||||
|
||||
def test_properties_named_small_graphs(self):
|
||||
G = nx.bull_graph()
|
||||
assert G.number_of_nodes() == 5
|
||||
assert G.number_of_edges() == 5
|
||||
assert sorted(d for n, d in G.degree()) == [1, 1, 2, 3, 3]
|
||||
assert nx.diameter(G) == 3
|
||||
assert nx.radius(G) == 2
|
||||
|
||||
G = nx.chvatal_graph()
|
||||
assert G.number_of_nodes() == 12
|
||||
assert G.number_of_edges() == 24
|
||||
assert list(d for n, d in G.degree()) == 12 * [4]
|
||||
assert nx.diameter(G) == 2
|
||||
assert nx.radius(G) == 2
|
||||
|
||||
G = nx.cubical_graph()
|
||||
assert G.number_of_nodes() == 8
|
||||
assert G.number_of_edges() == 12
|
||||
assert list(d for n, d in G.degree()) == 8 * [3]
|
||||
assert nx.diameter(G) == 3
|
||||
assert nx.radius(G) == 3
|
||||
|
||||
G = nx.desargues_graph()
|
||||
assert G.number_of_nodes() == 20
|
||||
assert G.number_of_edges() == 30
|
||||
assert list(d for n, d in G.degree()) == 20 * [3]
|
||||
|
||||
G = nx.diamond_graph()
|
||||
assert G.number_of_nodes() == 4
|
||||
assert sorted(d for n, d in G.degree()) == [2, 2, 3, 3]
|
||||
assert nx.diameter(G) == 2
|
||||
assert nx.radius(G) == 1
|
||||
|
||||
G = nx.dodecahedral_graph()
|
||||
assert G.number_of_nodes() == 20
|
||||
assert G.number_of_edges() == 30
|
||||
assert list(d for n, d in G.degree()) == 20 * [3]
|
||||
assert nx.diameter(G) == 5
|
||||
assert nx.radius(G) == 5
|
||||
|
||||
G = nx.frucht_graph()
|
||||
assert G.number_of_nodes() == 12
|
||||
assert G.number_of_edges() == 18
|
||||
assert list(d for n, d in G.degree()) == 12 * [3]
|
||||
assert nx.diameter(G) == 4
|
||||
assert nx.radius(G) == 3
|
||||
|
||||
G = nx.heawood_graph()
|
||||
assert G.number_of_nodes() == 14
|
||||
assert G.number_of_edges() == 21
|
||||
assert list(d for n, d in G.degree()) == 14 * [3]
|
||||
assert nx.diameter(G) == 3
|
||||
assert nx.radius(G) == 3
|
||||
|
||||
G = nx.hoffman_singleton_graph()
|
||||
assert G.number_of_nodes() == 50
|
||||
assert G.number_of_edges() == 175
|
||||
assert list(d for n, d in G.degree()) == 50 * [7]
|
||||
assert nx.diameter(G) == 2
|
||||
assert nx.radius(G) == 2
|
||||
|
||||
G = nx.house_graph()
|
||||
assert G.number_of_nodes() == 5
|
||||
assert G.number_of_edges() == 6
|
||||
assert sorted(d for n, d in G.degree()) == [2, 2, 2, 3, 3]
|
||||
assert nx.diameter(G) == 2
|
||||
assert nx.radius(G) == 2
|
||||
|
||||
G = nx.house_x_graph()
|
||||
assert G.number_of_nodes() == 5
|
||||
assert G.number_of_edges() == 8
|
||||
assert sorted(d for n, d in G.degree()) == [2, 3, 3, 4, 4]
|
||||
assert nx.diameter(G) == 2
|
||||
assert nx.radius(G) == 1
|
||||
|
||||
G = nx.icosahedral_graph()
|
||||
assert G.number_of_nodes() == 12
|
||||
assert G.number_of_edges() == 30
|
||||
assert list(d for n, d in G.degree()) == [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
|
||||
assert nx.diameter(G) == 3
|
||||
assert nx.radius(G) == 3
|
||||
|
||||
G = nx.krackhardt_kite_graph()
|
||||
assert G.number_of_nodes() == 10
|
||||
assert G.number_of_edges() == 18
|
||||
assert sorted(d for n, d in G.degree()) == [1, 2, 3, 3, 3, 4, 4, 5, 5, 6]
|
||||
|
||||
G = nx.moebius_kantor_graph()
|
||||
assert G.number_of_nodes() == 16
|
||||
assert G.number_of_edges() == 24
|
||||
assert list(d for n, d in G.degree()) == 16 * [3]
|
||||
assert nx.diameter(G) == 4
|
||||
|
||||
G = nx.octahedral_graph()
|
||||
assert G.number_of_nodes() == 6
|
||||
assert G.number_of_edges() == 12
|
||||
assert list(d for n, d in G.degree()) == 6 * [4]
|
||||
assert nx.diameter(G) == 2
|
||||
assert nx.radius(G) == 2
|
||||
|
||||
G = nx.pappus_graph()
|
||||
assert G.number_of_nodes() == 18
|
||||
assert G.number_of_edges() == 27
|
||||
assert list(d for n, d in G.degree()) == 18 * [3]
|
||||
assert nx.diameter(G) == 4
|
||||
|
||||
G = nx.petersen_graph()
|
||||
assert G.number_of_nodes() == 10
|
||||
assert G.number_of_edges() == 15
|
||||
assert list(d for n, d in G.degree()) == 10 * [3]
|
||||
assert nx.diameter(G) == 2
|
||||
assert nx.radius(G) == 2
|
||||
|
||||
G = nx.sedgewick_maze_graph()
|
||||
assert G.number_of_nodes() == 8
|
||||
assert G.number_of_edges() == 10
|
||||
assert sorted(d for n, d in G.degree()) == [1, 2, 2, 2, 3, 3, 3, 4]
|
||||
|
||||
G = nx.tetrahedral_graph()
|
||||
assert G.number_of_nodes() == 4
|
||||
assert G.number_of_edges() == 6
|
||||
assert list(d for n, d in G.degree()) == [3, 3, 3, 3]
|
||||
assert nx.diameter(G) == 1
|
||||
assert nx.radius(G) == 1
|
||||
|
||||
G = nx.truncated_cube_graph()
|
||||
assert G.number_of_nodes() == 24
|
||||
assert G.number_of_edges() == 36
|
||||
assert list(d for n, d in G.degree()) == 24 * [3]
|
||||
|
||||
G = nx.truncated_tetrahedron_graph()
|
||||
assert G.number_of_nodes() == 12
|
||||
assert G.number_of_edges() == 18
|
||||
assert list(d for n, d in G.degree()) == 12 * [3]
|
||||
|
||||
G = nx.tutte_graph()
|
||||
assert G.number_of_nodes() == 46
|
||||
assert G.number_of_edges() == 69
|
||||
assert list(d for n, d in G.degree()) == 46 * [3]
|
||||
|
||||
# Test create_using with directed or multigraphs on small graphs
|
||||
pytest.raises(nx.NetworkXError, nx.tutte_graph, create_using=nx.DiGraph)
|
||||
MG = nx.tutte_graph(create_using=nx.MultiGraph)
|
||||
assert sorted(MG.edges()) == sorted(G.edges())
|
|
@ -0,0 +1,48 @@
|
|||
import pytest
|
||||
|
||||
from networkx import is_isomorphic
|
||||
from networkx.exception import NetworkXError
|
||||
from networkx.testing import assert_nodes_equal
|
||||
from networkx.generators.spectral_graph_forge import spectral_graph_forge
|
||||
from networkx.generators import karate_club_graph
|
||||
|
||||
|
||||
def test_spectral_graph_forge():
|
||||
numpy = pytest.importorskip("numpy")
|
||||
scipy = pytest.importorskip("scipy")
|
||||
|
||||
G = karate_club_graph()
|
||||
|
||||
seed = 54321
|
||||
|
||||
# common cases, just checking node number preserving and difference
|
||||
# between identity and modularity cases
|
||||
H = spectral_graph_forge(G, 0.1, transformation="identity", seed=seed)
|
||||
assert_nodes_equal(G, H)
|
||||
|
||||
I = spectral_graph_forge(G, 0.1, transformation="identity", seed=seed)
|
||||
assert_nodes_equal(G, H)
|
||||
assert is_isomorphic(I, H)
|
||||
|
||||
I = spectral_graph_forge(G, 0.1, transformation="modularity", seed=seed)
|
||||
assert_nodes_equal(G, I)
|
||||
|
||||
assert not is_isomorphic(I, H)
|
||||
|
||||
# with all the eigenvectors, output graph is identical to the input one
|
||||
H = spectral_graph_forge(G, 1, transformation="modularity", seed=seed)
|
||||
assert_nodes_equal(G, H)
|
||||
assert is_isomorphic(G, H)
|
||||
|
||||
# invalid alpha input value, it is silently truncated in [0,1]
|
||||
H = spectral_graph_forge(G, -1, transformation="identity", seed=seed)
|
||||
assert_nodes_equal(G, H)
|
||||
|
||||
H = spectral_graph_forge(G, 10, transformation="identity", seed=seed)
|
||||
assert_nodes_equal(G, H)
|
||||
assert is_isomorphic(G, H)
|
||||
|
||||
# invalid transformation mode, checking the error raising
|
||||
pytest.raises(
|
||||
NetworkXError, spectral_graph_forge, G, 0.1, transformation="unknown", seed=seed
|
||||
)
|
|
@ -0,0 +1,63 @@
|
|||
"""Unit tests for the :mod:`networkx.generators.stochastic` module."""
|
||||
import pytest
|
||||
import networkx as nx
|
||||
|
||||
|
||||
class TestStochasticGraph:
|
||||
"""Unit tests for the :func:`~networkx.stochastic_graph` function.
|
||||
|
||||
"""
|
||||
|
||||
def test_default_weights(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_edge(0, 1)
|
||||
G.add_edge(0, 2)
|
||||
S = nx.stochastic_graph(G)
|
||||
assert nx.is_isomorphic(G, S)
|
||||
assert sorted(S.edges(data=True)) == [
|
||||
(0, 1, {"weight": 0.5}),
|
||||
(0, 2, {"weight": 0.5}),
|
||||
]
|
||||
|
||||
def test_in_place(self):
|
||||
"""Tests for an in-place reweighting of the edges of the graph.
|
||||
|
||||
"""
|
||||
G = nx.DiGraph()
|
||||
G.add_edge(0, 1, weight=1)
|
||||
G.add_edge(0, 2, weight=1)
|
||||
nx.stochastic_graph(G, copy=False)
|
||||
assert sorted(G.edges(data=True)) == [
|
||||
(0, 1, {"weight": 0.5}),
|
||||
(0, 2, {"weight": 0.5}),
|
||||
]
|
||||
|
||||
def test_arbitrary_weights(self):
|
||||
G = nx.DiGraph()
|
||||
G.add_edge(0, 1, weight=1)
|
||||
G.add_edge(0, 2, weight=1)
|
||||
S = nx.stochastic_graph(G)
|
||||
assert sorted(S.edges(data=True)) == [
|
||||
(0, 1, {"weight": 0.5}),
|
||||
(0, 2, {"weight": 0.5}),
|
||||
]
|
||||
|
||||
def test_multidigraph(self):
|
||||
G = nx.MultiDiGraph()
|
||||
G.add_edges_from([(0, 1), (0, 1), (0, 2), (0, 2)])
|
||||
S = nx.stochastic_graph(G)
|
||||
d = dict(weight=0.25)
|
||||
assert sorted(S.edges(data=True)) == [
|
||||
(0, 1, d),
|
||||
(0, 1, d),
|
||||
(0, 2, d),
|
||||
(0, 2, d),
|
||||
]
|
||||
|
||||
def test_graph_disallowed(self):
|
||||
with pytest.raises(nx.NetworkXNotImplemented):
|
||||
nx.stochastic_graph(nx.Graph())
|
||||
|
||||
def test_multigraph_disallowed(self):
|
||||
with pytest.raises(nx.NetworkXNotImplemented):
|
||||
nx.stochastic_graph(nx.MultiGraph())
|
|
@ -0,0 +1,91 @@
|
|||
"""Unit tests for the :mod:`networkx.generators.sudoku_graph` module."""
|
||||
|
||||
import pytest
|
||||
import networkx as nx
|
||||
|
||||
|
||||
def test_sudoku_negative():
|
||||
"""Raise an error when generating a Sudoku graph of order -1."""
|
||||
pytest.raises(nx.NetworkXError, nx.sudoku_graph, n=-1)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("n", [0, 1, 2, 3, 4])
|
||||
def test_sudoku_generator(n):
|
||||
"""Generate Sudoku graphs of various sizes and verify their properties."""
|
||||
G = nx.sudoku_graph(n)
|
||||
expected_nodes = n ** 4
|
||||
expected_degree = (n - 1) * (3 * n + 1)
|
||||
expected_edges = expected_nodes * expected_degree // 2
|
||||
assert not G.is_directed()
|
||||
assert not G.is_multigraph()
|
||||
assert G.number_of_nodes() == expected_nodes
|
||||
assert G.number_of_edges() == expected_edges
|
||||
assert all(d == expected_degree for _, d in G.degree)
|
||||
|
||||
if n == 2:
|
||||
assert sorted(G.neighbors(6)) == [2, 3, 4, 5, 7, 10, 14]
|
||||
elif n == 3:
|
||||
assert sorted(G.neighbors(42)) == [
|
||||
6,
|
||||
15,
|
||||
24,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
43,
|
||||
44,
|
||||
51,
|
||||
52,
|
||||
53,
|
||||
60,
|
||||
69,
|
||||
78,
|
||||
]
|
||||
elif n == 4:
|
||||
assert sorted(G.neighbors(0)) == [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
48,
|
||||
49,
|
||||
50,
|
||||
51,
|
||||
64,
|
||||
80,
|
||||
96,
|
||||
112,
|
||||
128,
|
||||
144,
|
||||
160,
|
||||
176,
|
||||
192,
|
||||
208,
|
||||
224,
|
||||
240,
|
||||
]
|
|
@ -0,0 +1,74 @@
|
|||
import networkx as nx
|
||||
from networkx.generators.trees import NIL
|
||||
from networkx.utils import arbitrary_element
|
||||
|
||||
|
||||
class TestPrefixTree:
|
||||
"""Unit tests for the prefix tree generator function."""
|
||||
|
||||
def test_basic(self):
|
||||
# This example is from the Wikipedia article "Trie"
|
||||
# <https://en.wikipedia.org/wiki/Trie>.
|
||||
strings = ["a", "to", "tea", "ted", "ten", "i", "in", "inn"]
|
||||
T, root = nx.prefix_tree(strings)
|
||||
|
||||
def source_label(v):
|
||||
return T.nodes[v]["source"]
|
||||
|
||||
# First, we check that the tree has the expected
|
||||
# structure. Recall that each node that corresponds to one of
|
||||
# the input strings has an edge to the NIL node.
|
||||
#
|
||||
# Consider the three children at level 1 in the trie.
|
||||
a, i, t = sorted(T[root], key=source_label)
|
||||
# Check the 'a' branch.
|
||||
assert len(T[a]) == 1
|
||||
nil = arbitrary_element(T[a])
|
||||
assert len(T[nil]) == 0
|
||||
# Check the 'i' branch.
|
||||
assert len(T[i]) == 2
|
||||
nil, in_ = sorted(T[i], key=source_label)
|
||||
assert len(T[nil]) == 0
|
||||
assert len(T[in_]) == 2
|
||||
nil, inn = sorted(T[in_], key=source_label)
|
||||
assert len(T[nil]) == 0
|
||||
assert len(T[inn]) == 1
|
||||
nil = arbitrary_element(T[inn])
|
||||
assert len(T[nil]) == 0
|
||||
# Check the 't' branch.
|
||||
te, to = sorted(T[t], key=source_label)
|
||||
assert len(T[to]) == 1
|
||||
nil = arbitrary_element(T[to])
|
||||
assert len(T[nil]) == 0
|
||||
tea, ted, ten = sorted(T[te], key=source_label)
|
||||
assert len(T[tea]) == 1
|
||||
assert len(T[ted]) == 1
|
||||
assert len(T[ten]) == 1
|
||||
nil = arbitrary_element(T[tea])
|
||||
assert len(T[nil]) == 0
|
||||
nil = arbitrary_element(T[ted])
|
||||
assert len(T[nil]) == 0
|
||||
nil = arbitrary_element(T[ten])
|
||||
assert len(T[nil]) == 0
|
||||
|
||||
# Next, we check that the "sources" of each of the nodes is the
|
||||
# rightmost letter in the string corresponding to the path to
|
||||
# that node.
|
||||
assert source_label(root) is None
|
||||
assert source_label(a) == "a"
|
||||
assert source_label(i) == "i"
|
||||
assert source_label(t) == "t"
|
||||
assert source_label(in_) == "n"
|
||||
assert source_label(inn) == "n"
|
||||
assert source_label(to) == "o"
|
||||
assert source_label(te) == "e"
|
||||
assert source_label(tea) == "a"
|
||||
assert source_label(ted) == "d"
|
||||
assert source_label(ten) == "n"
|
||||
assert source_label(NIL) == NIL
|
||||
|
||||
|
||||
def test_random_tree():
|
||||
"""Tests that a random tree is in fact a tree."""
|
||||
T = nx.random_tree(10, seed=1234)
|
||||
assert nx.is_tree(T)
|
|
@ -0,0 +1,14 @@
|
|||
"""Unit tests for the :mod:`networkx.generators.triads` module."""
|
||||
import pytest
|
||||
|
||||
from networkx import triad_graph
|
||||
|
||||
|
||||
def test_triad_graph():
|
||||
G = triad_graph("030T")
|
||||
assert [tuple(e) for e in ("ab", "ac", "cb")] == sorted(G.edges())
|
||||
|
||||
|
||||
def test_invalid_name():
|
||||
with pytest.raises(ValueError):
|
||||
triad_graph("bogus")
|
Loading…
Add table
Add a link
Reference in a new issue