test_chordal.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import pytest
  2. import networkx as nx
  3. class TestMCS:
  4. @classmethod
  5. def setup_class(cls):
  6. # simple graph
  7. connected_chordal_G = nx.Graph()
  8. connected_chordal_G.add_edges_from(
  9. [
  10. (1, 2),
  11. (1, 3),
  12. (2, 3),
  13. (2, 4),
  14. (3, 4),
  15. (3, 5),
  16. (3, 6),
  17. (4, 5),
  18. (4, 6),
  19. (5, 6),
  20. ]
  21. )
  22. cls.connected_chordal_G = connected_chordal_G
  23. chordal_G = nx.Graph()
  24. chordal_G.add_edges_from(
  25. [
  26. (1, 2),
  27. (1, 3),
  28. (2, 3),
  29. (2, 4),
  30. (3, 4),
  31. (3, 5),
  32. (3, 6),
  33. (4, 5),
  34. (4, 6),
  35. (5, 6),
  36. (7, 8),
  37. ]
  38. )
  39. chordal_G.add_node(9)
  40. cls.chordal_G = chordal_G
  41. non_chordal_G = nx.Graph()
  42. non_chordal_G.add_edges_from([(1, 2), (1, 3), (2, 4), (2, 5), (3, 4), (3, 5)])
  43. cls.non_chordal_G = non_chordal_G
  44. self_loop_G = nx.Graph()
  45. self_loop_G.add_edges_from([(1, 1)])
  46. cls.self_loop_G = self_loop_G
  47. @pytest.mark.parametrize("G", (nx.DiGraph(), nx.MultiGraph(), nx.MultiDiGraph()))
  48. def test_is_chordal_not_implemented(self, G):
  49. with pytest.raises(nx.NetworkXNotImplemented):
  50. nx.is_chordal(G)
  51. def test_is_chordal(self):
  52. assert not nx.is_chordal(self.non_chordal_G)
  53. assert nx.is_chordal(self.chordal_G)
  54. assert nx.is_chordal(self.connected_chordal_G)
  55. assert nx.is_chordal(nx.complete_graph(3))
  56. assert nx.is_chordal(nx.cycle_graph(3))
  57. assert not nx.is_chordal(nx.cycle_graph(5))
  58. with pytest.raises(nx.NetworkXError, match="Input graph is not chordal"):
  59. nx.is_chordal(self.self_loop_G)
  60. def test_induced_nodes(self):
  61. G = nx.generators.classic.path_graph(10)
  62. Induced_nodes = nx.find_induced_nodes(G, 1, 9, 2)
  63. assert Induced_nodes == {1, 2, 3, 4, 5, 6, 7, 8, 9}
  64. pytest.raises(
  65. nx.NetworkXTreewidthBoundExceeded, nx.find_induced_nodes, G, 1, 9, 1
  66. )
  67. Induced_nodes = nx.find_induced_nodes(self.chordal_G, 1, 6)
  68. assert Induced_nodes == {1, 2, 4, 6}
  69. pytest.raises(nx.NetworkXError, nx.find_induced_nodes, self.non_chordal_G, 1, 5)
  70. def test_graph_treewidth(self):
  71. with pytest.raises(nx.NetworkXError, match="Input graph is not chordal"):
  72. nx.chordal_graph_treewidth(self.non_chordal_G)
  73. def test_chordal_find_cliques(self):
  74. cliques = {
  75. frozenset([9]),
  76. frozenset([7, 8]),
  77. frozenset([1, 2, 3]),
  78. frozenset([2, 3, 4]),
  79. frozenset([3, 4, 5, 6]),
  80. }
  81. assert set(nx.chordal_graph_cliques(self.chordal_G)) == cliques
  82. with pytest.raises(nx.NetworkXError, match="Input graph is not chordal"):
  83. set(nx.chordal_graph_cliques(self.non_chordal_G))
  84. with pytest.raises(nx.NetworkXError, match="Input graph is not chordal"):
  85. set(nx.chordal_graph_cliques(self.self_loop_G))
  86. def test_chordal_find_cliques_path(self):
  87. G = nx.path_graph(10)
  88. cliqueset = nx.chordal_graph_cliques(G)
  89. for u, v in G.edges():
  90. assert frozenset([u, v]) in cliqueset or frozenset([v, u]) in cliqueset
  91. def test_chordal_find_cliquesCC(self):
  92. cliques = {frozenset([1, 2, 3]), frozenset([2, 3, 4]), frozenset([3, 4, 5, 6])}
  93. cgc = nx.chordal_graph_cliques
  94. assert set(cgc(self.connected_chordal_G)) == cliques
  95. def test_complete_to_chordal_graph(self):
  96. fgrg = nx.fast_gnp_random_graph
  97. test_graphs = [
  98. nx.barbell_graph(6, 2),
  99. nx.cycle_graph(15),
  100. nx.wheel_graph(20),
  101. nx.grid_graph([10, 4]),
  102. nx.ladder_graph(15),
  103. nx.star_graph(5),
  104. nx.bull_graph(),
  105. fgrg(20, 0.3, seed=1),
  106. ]
  107. for G in test_graphs:
  108. H, a = nx.complete_to_chordal_graph(G)
  109. assert nx.is_chordal(H)
  110. assert len(a) == H.number_of_nodes()
  111. if nx.is_chordal(G):
  112. assert G.number_of_edges() == H.number_of_edges()
  113. assert set(a.values()) == {0}
  114. else:
  115. assert len(set(a.values())) == H.number_of_nodes()