test_boundary.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. """Unit tests for the :mod:`networkx.algorithms.boundary` module."""
  2. from itertools import combinations
  3. import pytest
  4. import networkx as nx
  5. from networkx import convert_node_labels_to_integers as cnlti
  6. from networkx.utils import edges_equal
  7. class TestNodeBoundary:
  8. """Unit tests for the :func:`~networkx.node_boundary` function."""
  9. def test_null_graph(self):
  10. """Tests that the null graph has empty node boundaries."""
  11. null = nx.null_graph()
  12. assert nx.node_boundary(null, []) == set()
  13. assert nx.node_boundary(null, [], []) == set()
  14. assert nx.node_boundary(null, [1, 2, 3]) == set()
  15. assert nx.node_boundary(null, [1, 2, 3], [4, 5, 6]) == set()
  16. assert nx.node_boundary(null, [1, 2, 3], [3, 4, 5]) == set()
  17. def test_path_graph(self):
  18. P10 = cnlti(nx.path_graph(10), first_label=1)
  19. assert nx.node_boundary(P10, []) == set()
  20. assert nx.node_boundary(P10, [], []) == set()
  21. assert nx.node_boundary(P10, [1, 2, 3]) == {4}
  22. assert nx.node_boundary(P10, [4, 5, 6]) == {3, 7}
  23. assert nx.node_boundary(P10, [3, 4, 5, 6, 7]) == {2, 8}
  24. assert nx.node_boundary(P10, [8, 9, 10]) == {7}
  25. assert nx.node_boundary(P10, [4, 5, 6], [9, 10]) == set()
  26. def test_complete_graph(self):
  27. K10 = cnlti(nx.complete_graph(10), first_label=1)
  28. assert nx.node_boundary(K10, []) == set()
  29. assert nx.node_boundary(K10, [], []) == set()
  30. assert nx.node_boundary(K10, [1, 2, 3]) == {4, 5, 6, 7, 8, 9, 10}
  31. assert nx.node_boundary(K10, [4, 5, 6]) == {1, 2, 3, 7, 8, 9, 10}
  32. assert nx.node_boundary(K10, [3, 4, 5, 6, 7]) == {1, 2, 8, 9, 10}
  33. assert nx.node_boundary(K10, [4, 5, 6], []) == set()
  34. assert nx.node_boundary(K10, K10) == set()
  35. assert nx.node_boundary(K10, [1, 2, 3], [3, 4, 5]) == {4, 5}
  36. def test_petersen(self):
  37. """Check boundaries in the petersen graph
  38. cheeger(G,k)=min(|bdy(S)|/|S| for |S|=k, 0<k<=|V(G)|/2)
  39. """
  40. def cheeger(G, k):
  41. return min(len(nx.node_boundary(G, nn)) / k for nn in combinations(G, k))
  42. P = nx.petersen_graph()
  43. assert cheeger(P, 1) == pytest.approx(3.00, abs=1e-2)
  44. assert cheeger(P, 2) == pytest.approx(2.00, abs=1e-2)
  45. assert cheeger(P, 3) == pytest.approx(1.67, abs=1e-2)
  46. assert cheeger(P, 4) == pytest.approx(1.00, abs=1e-2)
  47. assert cheeger(P, 5) == pytest.approx(0.80, abs=1e-2)
  48. def test_directed(self):
  49. """Tests the node boundary of a directed graph."""
  50. G = nx.DiGraph([(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)])
  51. S = {0, 1}
  52. boundary = nx.node_boundary(G, S)
  53. expected = {2}
  54. assert boundary == expected
  55. def test_multigraph(self):
  56. """Tests the node boundary of a multigraph."""
  57. G = nx.MultiGraph(list(nx.cycle_graph(5).edges()) * 2)
  58. S = {0, 1}
  59. boundary = nx.node_boundary(G, S)
  60. expected = {2, 4}
  61. assert boundary == expected
  62. def test_multidigraph(self):
  63. """Tests the edge boundary of a multdiigraph."""
  64. edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)]
  65. G = nx.MultiDiGraph(edges * 2)
  66. S = {0, 1}
  67. boundary = nx.node_boundary(G, S)
  68. expected = {2}
  69. assert boundary == expected
  70. class TestEdgeBoundary:
  71. """Unit tests for the :func:`~networkx.edge_boundary` function."""
  72. def test_null_graph(self):
  73. null = nx.null_graph()
  74. assert list(nx.edge_boundary(null, [])) == []
  75. assert list(nx.edge_boundary(null, [], [])) == []
  76. assert list(nx.edge_boundary(null, [1, 2, 3])) == []
  77. assert list(nx.edge_boundary(null, [1, 2, 3], [4, 5, 6])) == []
  78. assert list(nx.edge_boundary(null, [1, 2, 3], [3, 4, 5])) == []
  79. def test_path_graph(self):
  80. P10 = cnlti(nx.path_graph(10), first_label=1)
  81. assert list(nx.edge_boundary(P10, [])) == []
  82. assert list(nx.edge_boundary(P10, [], [])) == []
  83. assert list(nx.edge_boundary(P10, [1, 2, 3])) == [(3, 4)]
  84. assert sorted(nx.edge_boundary(P10, [4, 5, 6])) == [(4, 3), (6, 7)]
  85. assert sorted(nx.edge_boundary(P10, [3, 4, 5, 6, 7])) == [(3, 2), (7, 8)]
  86. assert list(nx.edge_boundary(P10, [8, 9, 10])) == [(8, 7)]
  87. assert sorted(nx.edge_boundary(P10, [4, 5, 6], [9, 10])) == []
  88. assert list(nx.edge_boundary(P10, [1, 2, 3], [3, 4, 5])) == [(2, 3), (3, 4)]
  89. def test_complete_graph(self):
  90. K10 = cnlti(nx.complete_graph(10), first_label=1)
  91. def ilen(iterable):
  92. return sum(1 for i in iterable)
  93. assert list(nx.edge_boundary(K10, [])) == []
  94. assert list(nx.edge_boundary(K10, [], [])) == []
  95. assert ilen(nx.edge_boundary(K10, [1, 2, 3])) == 21
  96. assert ilen(nx.edge_boundary(K10, [4, 5, 6, 7])) == 24
  97. assert ilen(nx.edge_boundary(K10, [3, 4, 5, 6, 7])) == 25
  98. assert ilen(nx.edge_boundary(K10, [8, 9, 10])) == 21
  99. assert edges_equal(
  100. nx.edge_boundary(K10, [4, 5, 6], [9, 10]),
  101. [(4, 9), (4, 10), (5, 9), (5, 10), (6, 9), (6, 10)],
  102. )
  103. assert edges_equal(
  104. nx.edge_boundary(K10, [1, 2, 3], [3, 4, 5]),
  105. [(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5)],
  106. )
  107. def test_directed(self):
  108. """Tests the edge boundary of a directed graph."""
  109. G = nx.DiGraph([(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)])
  110. S = {0, 1}
  111. boundary = list(nx.edge_boundary(G, S))
  112. expected = [(1, 2)]
  113. assert boundary == expected
  114. def test_multigraph(self):
  115. """Tests the edge boundary of a multigraph."""
  116. G = nx.MultiGraph(list(nx.cycle_graph(5).edges()) * 2)
  117. S = {0, 1}
  118. boundary = list(nx.edge_boundary(G, S))
  119. expected = [(0, 4), (0, 4), (1, 2), (1, 2)]
  120. assert boundary == expected
  121. def test_multidigraph(self):
  122. """Tests the edge boundary of a multdiigraph."""
  123. edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)]
  124. G = nx.MultiDiGraph(edges * 2)
  125. S = {0, 1}
  126. boundary = list(nx.edge_boundary(G, S))
  127. expected = [(1, 2), (1, 2)]
  128. assert boundary == expected