sudoku.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. """Generator for Sudoku graphs
  2. This module gives a generator for n-Sudoku graphs. It can be used to develop
  3. algorithms for solving or generating Sudoku puzzles.
  4. A completed Sudoku grid is a 9x9 array of integers between 1 and 9, with no
  5. number appearing twice in the same row, column, or 3x3 box.
  6. +---------+---------+---------+
  7. | | 8 6 4 | | 3 7 1 | | 2 5 9 |
  8. | | 3 2 5 | | 8 4 9 | | 7 6 1 |
  9. | | 9 7 1 | | 2 6 5 | | 8 4 3 |
  10. +---------+---------+---------+
  11. | | 4 3 6 | | 1 9 2 | | 5 8 7 |
  12. | | 1 9 8 | | 6 5 7 | | 4 3 2 |
  13. | | 2 5 7 | | 4 8 3 | | 9 1 6 |
  14. +---------+---------+---------+
  15. | | 6 8 9 | | 7 3 4 | | 1 2 5 |
  16. | | 7 1 3 | | 5 2 8 | | 6 9 4 |
  17. | | 5 4 2 | | 9 1 6 | | 3 7 8 |
  18. +---------+---------+---------+
  19. The Sudoku graph is an undirected graph with 81 vertices, corresponding to
  20. the cells of a Sudoku grid. It is a regular graph of degree 20. Two distinct
  21. vertices are adjacent if and only if the corresponding cells belong to the
  22. same row, column, or box. A completed Sudoku grid corresponds to a vertex
  23. coloring of the Sudoku graph with nine colors.
  24. More generally, the n-Sudoku graph is a graph with n^4 vertices, corresponding
  25. to the cells of an n^2 by n^2 grid. Two distinct vertices are adjacent if and
  26. only if they belong to the same row, column, or n by n box.
  27. References
  28. ----------
  29. .. [1] Herzberg, A. M., & Murty, M. R. (2007). Sudoku squares and chromatic
  30. polynomials. Notices of the AMS, 54(6), 708-717.
  31. .. [2] Sander, Torsten (2009), "Sudoku graphs are integral",
  32. Electronic Journal of Combinatorics, 16 (1): Note 25, 7pp, MR 2529816
  33. .. [3] Wikipedia contributors. "Glossary of Sudoku." Wikipedia, The Free
  34. Encyclopedia, 3 Dec. 2019. Web. 22 Dec. 2019.
  35. """
  36. import networkx as nx
  37. from networkx.exception import NetworkXError
  38. __all__ = ["sudoku_graph"]
  39. @nx._dispatchable(graphs=None, returns_graph=True)
  40. def sudoku_graph(n=3):
  41. """Returns the n-Sudoku graph. The default value of n is 3.
  42. The n-Sudoku graph is a graph with n^4 vertices, corresponding to the
  43. cells of an n^2 by n^2 grid. Two distinct vertices are adjacent if and
  44. only if they belong to the same row, column, or n-by-n box.
  45. Parameters
  46. ----------
  47. n: integer
  48. The order of the Sudoku graph, equal to the square root of the
  49. number of rows. The default is 3.
  50. Returns
  51. -------
  52. NetworkX graph
  53. The n-Sudoku graph Sud(n).
  54. Examples
  55. --------
  56. >>> G = nx.sudoku_graph()
  57. >>> G.number_of_nodes()
  58. 81
  59. >>> G.number_of_edges()
  60. 810
  61. >>> sorted(G.neighbors(42))
  62. [6, 15, 24, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 44, 51, 52, 53, 60, 69, 78]
  63. >>> G = nx.sudoku_graph(2)
  64. >>> G.number_of_nodes()
  65. 16
  66. >>> G.number_of_edges()
  67. 56
  68. References
  69. ----------
  70. .. [1] Herzberg, A. M., & Murty, M. R. (2007). Sudoku squares and chromatic
  71. polynomials. Notices of the AMS, 54(6), 708-717.
  72. .. [2] Sander, Torsten (2009), "Sudoku graphs are integral",
  73. Electronic Journal of Combinatorics, 16 (1): Note 25, 7pp, MR 2529816
  74. .. [3] Wikipedia contributors. "Glossary of Sudoku." Wikipedia, The Free
  75. Encyclopedia, 3 Dec. 2019. Web. 22 Dec. 2019.
  76. """
  77. if n < 0:
  78. raise NetworkXError("The order must be greater than or equal to zero.")
  79. n2 = n * n
  80. n3 = n2 * n
  81. n4 = n3 * n
  82. # Construct an empty graph with n^4 nodes
  83. G = nx.empty_graph(n4)
  84. # A Sudoku graph of order 0 or 1 has no edges
  85. if n < 2:
  86. return G
  87. # Add edges for cells in the same row
  88. for row_no in range(n2):
  89. row_start = row_no * n2
  90. for j in range(1, n2):
  91. for i in range(j):
  92. G.add_edge(row_start + i, row_start + j)
  93. # Add edges for cells in the same column
  94. for col_no in range(n2):
  95. for j in range(col_no, n4, n2):
  96. for i in range(col_no, j, n2):
  97. G.add_edge(i, j)
  98. # Add edges for cells in the same box
  99. for band_no in range(n):
  100. for stack_no in range(n):
  101. box_start = n3 * band_no + n * stack_no
  102. for j in range(1, n2):
  103. for i in range(j):
  104. u = box_start + (i % n) + n2 * (i // n)
  105. v = box_start + (j % n) + n2 * (j // n)
  106. G.add_edge(u, v)
  107. return G