Fixed database typo and removed unnecessary class identifier.

This commit is contained in:
Batuhan Berk Başoğlu 2020-10-14 10:10:37 -04:00
parent 00ad49a143
commit 45fb349a7d
5098 changed files with 952558 additions and 85 deletions

View file

@ -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

View 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]

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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())

View file

@ -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)

View 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])

View file

@ -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())

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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],
)

View file

@ -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)

View file

@ -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)

View 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)

View 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)

View file

@ -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)))

View file

@ -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

View file

@ -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]],
)

View file

@ -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

View 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())

View file

@ -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
)

View file

@ -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())

View file

@ -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,
]

View file

@ -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)

View file

@ -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")