回溯算法解决数独Lua实现 - 图1

    1. sudoko = {
    2. {8, 0, 0, 0, 0, 0, 0, 0, 0},
    3. {0, 0, 3, 6, 0, 0, 0, 0, 0},
    4. {0, 7, 0, 0, 9, 0, 2, 0, 0},
    5. {0, 5, 0, 0, 0, 7, 0, 0, 0},
    6. {0, 0, 0, 0, 4, 5, 7, 0, 0},
    7. {0, 0, 0, 1, 0, 0, 0, 3, 0},
    8. {0, 0, 1, 0, 0, 0, 0, 6, 8},
    9. {0, 0, 8, 5, 0, 0, 0, 1, 0},
    10. {0, 9, 0, 0, 0, 0, 4, 0, 0}
    11. };
    12. function check(row, line,number,matrix)
    13. --判断该行该列是否有重复数字
    14. for i = 1 ,9 do
    15. if matrix[row][i] == number or matrix[i][line] == number then
    16. return false
    17. end
    18. end
    19. --判断小九宫格是否有重复
    20. local tempRow = math.ceil (row / 3) - 1
    21. local tempLine =math.ceil (line/ 3) - 1
    22. for i = 1,3 do
    23. for j = 1,3 do
    24. if (matrix[tempRow * 3 + i][tempLine * 3 + j] == number) then
    25. return false
    26. end
    27. end
    28. end
    29. return true
    30. end
    31. function printArray(matrix)
    32. for k,v in ipairs(matrix) do
    33. print(table.concat(v,","))
    34. end
    35. end
    36. function backTrace(i,j,matrix)
    37. --结尾
    38. if i == 9 and j == 10 then
    39. printArray(matrix)
    40. return
    41. end
    42. --到达列尾
    43. if j == 10 then
    44. j = 1
    45. i = i +1
    46. end
    47. if (matrix[i][j] == 0) then
    48. for k = 1 ,9 do
    49. if check(i, j, k,matrix) then
    50. matrix[i][j] = k
    51. backTrace(i, j + 1,matrix)
    52. --回溯还原
    53. matrix[i][j] = 0;
    54. end
    55. end
    56. else
    57. --下个位置
    58. backTrace(i, j + 1,matrix);
    59. end
    60. end
    61. backTrace(1,1,sudoko)
    1. --优化版本
    2. sudoko = {}
    3. --初始化
    4. sudoko.matrix = {
    5. {8, 0, 0, 0, 0, 0, 0, 0, 0},
    6. {0, 0, 3, 6, 0, 0, 0, 0, 0},
    7. {0, 7, 0, 0, 9, 0, 2, 0, 0},
    8. {0, 5, 0, 0, 0, 7, 0, 0, 0},
    9. {0, 0, 0, 0, 4, 5, 7, 0, 0},
    10. {0, 0, 0, 1, 0, 0, 0, 3, 0},
    11. {0, 0, 1, 0, 0, 0, 0, 6, 8},
    12. {0, 0, 8, 5, 0, 0, 0, 1, 0},
    13. {0, 9, 0, 0, 0, 0, 4, 0, 0}
    14. };
    15. sudoko.count = 0
    16. function sudoko:check(row, line,number)
    17. local matrix = self.matrix
    18. --判断该行该列是否有重复数字
    19. for i = 1 ,9 do
    20. if matrix[row][i] == number or matrix[i][line] == number then
    21. return false
    22. end
    23. end
    24. --判断小九宫格是否有重复
    25. local tempRow = math.ceil (row / 3) - 1
    26. local tempLine =math.ceil (line/ 3) - 1
    27. for i = 1,3 do
    28. for j = 1,3 do
    29. if (matrix[tempRow * 3 + i][tempLine * 3 + j] == number) then
    30. return false
    31. end
    32. end
    33. end
    34. return true
    35. end
    36. function sudoko:printArray()
    37. local matrix = self.matrix
    38. for k,v in ipairs(matrix) do
    39. print(table.concat(v,","))
    40. end
    41. print("统计backTrace调用次数:" .. self.count)
    42. end
    43. function sudoko:backTrace(i,j)
    44. local matrix = self.matrix
    45. --统计函数调用次数
    46. self.count = self.count + 1
    47. --结尾
    48. if i >= 9 and j >= 10 then
    49. self:printArray()
    50. return true
    51. end
    52. --到达列尾
    53. if j == 10 then
    54. i = i +1
    55. j = 1
    56. end
    57. if (matrix[i][j] == 0) then
    58. for k = 1 ,9 do
    59. if self:check(i, j, k) then
    60. matrix[i][j] = k
    61. if self:backTrace(i, j + 1) then
    62. return true
    63. end
    64. --回溯还原
    65. matrix[i][j] = 0;
    66. end
    67. end
    68. else
    69. --下个位置
    70. return self:backTrace(i, j + 1);
    71. end
    72. end
    73. sudoko:backTrace(1,1)

    优化之后backTrace函数调用次数72097次,之前3031697次
    参考
    http://blog.csdn.net/tianyaleixiaowu/article/details/50912924