test_lattice.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. """Unit tests for the :mod:`networkx.generators.lattice` module."""
  2. from itertools import product
  3. import pytest
  4. import networkx as nx
  5. from networkx.utils import edges_equal
  6. class TestGrid2DGraph:
  7. """Unit tests for :func:`networkx.generators.lattice.grid_2d_graph`"""
  8. def test_number_of_vertices(self):
  9. m, n = 5, 6
  10. G = nx.grid_2d_graph(m, n)
  11. assert len(G) == m * n
  12. def test_degree_distribution(self):
  13. m, n = 5, 6
  14. G = nx.grid_2d_graph(m, n)
  15. expected_histogram = [0, 0, 4, 2 * (m + n) - 8, (m - 2) * (n - 2)]
  16. assert nx.degree_histogram(G) == expected_histogram
  17. def test_directed(self):
  18. m, n = 5, 6
  19. G = nx.grid_2d_graph(m, n)
  20. H = nx.grid_2d_graph(m, n, create_using=nx.DiGraph())
  21. assert H.succ == G.adj
  22. assert H.pred == G.adj
  23. def test_multigraph(self):
  24. m, n = 5, 6
  25. G = nx.grid_2d_graph(m, n)
  26. H = nx.grid_2d_graph(m, n, create_using=nx.MultiGraph())
  27. assert list(H.edges()) == list(G.edges())
  28. def test_periodic(self):
  29. G = nx.grid_2d_graph(0, 0, periodic=True)
  30. assert dict(G.degree()) == {}
  31. for m, n, H in [
  32. (2, 2, nx.cycle_graph(4)),
  33. (1, 7, nx.cycle_graph(7)),
  34. (7, 1, nx.cycle_graph(7)),
  35. (2, 5, nx.circular_ladder_graph(5)),
  36. (5, 2, nx.circular_ladder_graph(5)),
  37. (2, 4, nx.cubical_graph()),
  38. (4, 2, nx.cubical_graph()),
  39. ]:
  40. G = nx.grid_2d_graph(m, n, periodic=True)
  41. assert nx.could_be_isomorphic(G, H)
  42. def test_periodic_iterable(self):
  43. m, n = 3, 7
  44. for a, b in product([0, 1], [0, 1]):
  45. G = nx.grid_2d_graph(m, n, periodic=(a, b))
  46. assert G.number_of_nodes() == m * n
  47. assert G.number_of_edges() == (m + a - 1) * n + (n + b - 1) * m
  48. def test_periodic_directed(self):
  49. G = nx.grid_2d_graph(4, 2, periodic=True)
  50. H = nx.grid_2d_graph(4, 2, periodic=True, create_using=nx.DiGraph())
  51. assert H.succ == G.adj
  52. assert H.pred == G.adj
  53. def test_periodic_multigraph(self):
  54. G = nx.grid_2d_graph(4, 2, periodic=True)
  55. H = nx.grid_2d_graph(4, 2, periodic=True, create_using=nx.MultiGraph())
  56. assert list(G.edges()) == list(H.edges())
  57. def test_exceptions(self):
  58. pytest.raises(nx.NetworkXError, nx.grid_2d_graph, -3, 2)
  59. pytest.raises(nx.NetworkXError, nx.grid_2d_graph, 3, -2)
  60. pytest.raises(TypeError, nx.grid_2d_graph, 3.3, 2)
  61. pytest.raises(TypeError, nx.grid_2d_graph, 3, 2.2)
  62. def test_node_input(self):
  63. G = nx.grid_2d_graph(4, 2, periodic=True)
  64. H = nx.grid_2d_graph(range(4), range(2), periodic=True)
  65. assert nx.is_isomorphic(H, G)
  66. H = nx.grid_2d_graph("abcd", "ef", periodic=True)
  67. assert nx.is_isomorphic(H, G)
  68. G = nx.grid_2d_graph(5, 6)
  69. H = nx.grid_2d_graph(range(5), range(6))
  70. assert edges_equal(H, G)
  71. class TestGridGraph:
  72. """Unit tests for :func:`networkx.generators.lattice.grid_graph`"""
  73. def test_grid_graph(self):
  74. """grid_graph([n,m]) is a connected simple graph with the
  75. following properties:
  76. number_of_nodes = n*m
  77. degree_histogram = [0,0,4,2*(n+m)-8,(n-2)*(m-2)]
  78. """
  79. for n, m in [(3, 5), (5, 3), (4, 5), (5, 4)]:
  80. dim = [n, m]
  81. g = nx.grid_graph(dim)
  82. assert len(g) == n * m
  83. assert nx.degree_histogram(g) == [
  84. 0,
  85. 0,
  86. 4,
  87. 2 * (n + m) - 8,
  88. (n - 2) * (m - 2),
  89. ]
  90. for n, m in [(1, 5), (5, 1)]:
  91. dim = [n, m]
  92. g = nx.grid_graph(dim)
  93. assert len(g) == n * m
  94. assert nx.is_isomorphic(g, nx.path_graph(5))
  95. # mg = nx.grid_graph([n,m], create_using=MultiGraph())
  96. # assert_equal(mg.edges(), g.edges())
  97. def test_node_input(self):
  98. G = nx.grid_graph([range(7, 9), range(3, 6)])
  99. assert len(G) == 2 * 3
  100. assert nx.is_isomorphic(G, nx.grid_graph([2, 3]))
  101. def test_periodic_iterable(self):
  102. m, n, k = 3, 7, 5
  103. for a, b, c in product([0, 1], [0, 1], [0, 1]):
  104. G = nx.grid_graph([m, n, k], periodic=(a, b, c))
  105. num_e = (m + a - 1) * n * k + (n + b - 1) * m * k + (k + c - 1) * m * n
  106. assert G.number_of_nodes() == m * n * k
  107. assert G.number_of_edges() == num_e
  108. class TestHypercubeGraph:
  109. """Unit tests for :func:`networkx.generators.lattice.hypercube_graph`"""
  110. def test_special_cases(self):
  111. for n, H in [
  112. (0, nx.null_graph()),
  113. (1, nx.path_graph(2)),
  114. (2, nx.cycle_graph(4)),
  115. (3, nx.cubical_graph()),
  116. ]:
  117. G = nx.hypercube_graph(n)
  118. assert nx.could_be_isomorphic(G, H)
  119. def test_degree_distribution(self):
  120. for n in range(1, 10):
  121. G = nx.hypercube_graph(n)
  122. expected_histogram = [0] * n + [2**n]
  123. assert nx.degree_histogram(G) == expected_histogram
  124. class TestTriangularLatticeGraph:
  125. "Tests for :func:`networkx.generators.lattice.triangular_lattice_graph`"
  126. def test_lattice_points(self):
  127. """Tests that the graph is really a triangular lattice."""
  128. for m, n in [(2, 3), (2, 2), (2, 1), (3, 3), (3, 2), (3, 4)]:
  129. G = nx.triangular_lattice_graph(m, n)
  130. N = (n + 1) // 2
  131. assert len(G) == (m + 1) * (1 + N) - (n % 2) * ((m + 1) // 2)
  132. for i, j in G.nodes():
  133. nbrs = G[(i, j)]
  134. if i < N:
  135. assert (i + 1, j) in nbrs
  136. if j < m:
  137. assert (i, j + 1) in nbrs
  138. if j < m and (i > 0 or j % 2) and (i < N or (j + 1) % 2):
  139. assert (i + 1, j + 1) in nbrs or (i - 1, j + 1) in nbrs
  140. def test_directed(self):
  141. """Tests for creating a directed triangular lattice."""
  142. G = nx.triangular_lattice_graph(3, 4, create_using=nx.Graph())
  143. H = nx.triangular_lattice_graph(3, 4, create_using=nx.DiGraph())
  144. assert H.is_directed()
  145. for u, v in H.edges():
  146. assert v[1] >= u[1]
  147. if v[1] == u[1]:
  148. assert v[0] > u[0]
  149. def test_multigraph(self):
  150. """Tests for creating a triangular lattice multigraph."""
  151. G = nx.triangular_lattice_graph(3, 4, create_using=nx.Graph())
  152. H = nx.triangular_lattice_graph(3, 4, create_using=nx.MultiGraph())
  153. assert list(H.edges()) == list(G.edges())
  154. def test_periodic(self):
  155. G = nx.triangular_lattice_graph(4, 6, periodic=True)
  156. assert len(G) == 12
  157. assert G.size() == 36
  158. # all degrees are 6
  159. assert len([n for n, d in G.degree() if d != 6]) == 0
  160. G = nx.triangular_lattice_graph(5, 7, periodic=True)
  161. TLG = nx.triangular_lattice_graph
  162. pytest.raises(nx.NetworkXError, TLG, 2, 4, periodic=True)
  163. pytest.raises(nx.NetworkXError, TLG, 4, 4, periodic=True)
  164. pytest.raises(nx.NetworkXError, TLG, 2, 6, periodic=True)
  165. class TestHexagonalLatticeGraph:
  166. "Tests for :func:`networkx.generators.lattice.hexagonal_lattice_graph`"
  167. def test_lattice_points(self):
  168. """Tests that the graph is really a hexagonal lattice."""
  169. for m, n in [(4, 5), (4, 4), (4, 3), (3, 2), (3, 3), (3, 5)]:
  170. G = nx.hexagonal_lattice_graph(m, n)
  171. assert len(G) == 2 * (m + 1) * (n + 1) - 2
  172. C_6 = nx.cycle_graph(6)
  173. hexagons = [
  174. [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)],
  175. [(0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4)],
  176. [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3)],
  177. [(2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2)],
  178. [(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4)],
  179. ]
  180. for hexagon in hexagons:
  181. assert nx.is_isomorphic(G.subgraph(hexagon), C_6)
  182. def test_directed(self):
  183. """Tests for creating a directed hexagonal lattice."""
  184. G = nx.hexagonal_lattice_graph(3, 5, create_using=nx.Graph())
  185. H = nx.hexagonal_lattice_graph(3, 5, create_using=nx.DiGraph())
  186. assert H.is_directed()
  187. pos = nx.get_node_attributes(H, "pos")
  188. for u, v in H.edges():
  189. assert pos[v][1] >= pos[u][1]
  190. if pos[v][1] == pos[u][1]:
  191. assert pos[v][0] > pos[u][0]
  192. def test_multigraph(self):
  193. """Tests for creating a hexagonal lattice multigraph."""
  194. G = nx.hexagonal_lattice_graph(3, 5, create_using=nx.Graph())
  195. H = nx.hexagonal_lattice_graph(3, 5, create_using=nx.MultiGraph())
  196. assert list(H.edges()) == list(G.edges())
  197. def test_periodic(self):
  198. G = nx.hexagonal_lattice_graph(4, 6, periodic=True)
  199. assert len(G) == 48
  200. assert G.size() == 72
  201. # all degrees are 3
  202. assert len([n for n, d in G.degree() if d != 3]) == 0
  203. G = nx.hexagonal_lattice_graph(5, 8, periodic=True)
  204. HLG = nx.hexagonal_lattice_graph
  205. pytest.raises(nx.NetworkXError, HLG, 2, 7, periodic=True)
  206. pytest.raises(nx.NetworkXError, HLG, 1, 4, periodic=True)
  207. pytest.raises(nx.NetworkXError, HLG, 2, 1, periodic=True)