鱼C论坛

 找回密码
 立即注册
查看: 1925|回复: 2

[技术交流] Python解数独(回溯算法,代码少于 60 行)

[复制链接]
发表于 2019-1-3 17:55:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
前些日子折腾起数独游戏,有几关愣是打不过去,算了好久都没结果(智商看来不够。。),于是就考虑要不要开个挂。。(原谅水货的困扰。。),之前学 Java 的时候,不知道从哪里整来了一份代码,正好是针对数独解法的,但是年代久远,已不知出处。。在此先谢过那位贡献原创的大神,于是依葫芦画瓢,用 Python 翻了一版,不多说,代码如下:

  1. #coding=utf-8

  2. #初始化数独的二维数组
  3. sudoku = [
  4.         [0, 0, 0, 0, 0, 4, 0, 1, 8],
  5.         [0, 0, 0, 0, 0, 0, 0, 6, 0],
  6.         [0, 9, 8, 0, 7, 5, 0, 0, 0],
  7.         [1, 0, 0, 3, 0, 0, 0, 0, 0],
  8.         [0, 5, 0, 0, 0, 0, 0, 2, 0],
  9.         [0, 0, 0, 0, 0, 2, 0, 0, 6],
  10.         [0, 0, 0, 4, 1, 0, 6, 3, 0],
  11.         [0, 2, 0, 0, 0, 0, 0, 0, 0],
  12.         [8, 6, 0, 7, 0, 0, 0, 0, 0]]

  13. matrix = sudoku[:]

  14. #验证算法,判断数独内部是否有不合规填充
  15. def suCheck(row, line, value) :
  16.         #行与列的验证
  17.         for i in range(9) :
  18.                 if (matrix[row][i] == value) or (matrix[i][line] == value) :
  19.                         return False
  20.         #小九宫格验证
  21.         tempRow = row // 3
  22.         tempLine = line // 3
  23.         for i in range(3) :
  24.                 for j in range(3) :
  25.                         if (matrix[tempRow * 3 + i][tempLine * 3 + j] == value) :
  26.                                 return False
  27.         return True

  28. #递归算法,填充数独
  29. def backTrace(i = 0, j = 0) :
  30.         if (i == 8) and (j == 9) :
  31.                 print('数独填充完毕:')
  32.                 printSudoku()
  33.                 return
  34.         if j == 9 :
  35.                 i += 1
  36.                 j = 0
  37.         if matrix[i][j] == 0 :
  38.                 for each in range(1, 10) :
  39.                         if suCheck(i, j, each) :
  40.                                 matrix[i][j] = each
  41.                                 backTrace(i, j + 1)
  42.                                 matrix[i][j] = 0
  43.         else :
  44.                 backTrace(i, j + 1)

  45. def printSudoku() :
  46.         for i in range(9) :
  47.                 for j in range(9) :
  48.                         print(matrix[i][j], end='  ')
  49.                 print()
  50.         print()

  51. backTrace()
复制代码


用回溯算法写数独的解法,这里肯定不是第一例了(毕竟很多年前就已经有用 Java 解出来的),但是用 Python 写的回溯,看了很久一直没看懂,不明白中间为何用到那么多的字符串下的 pop() 方法,所以这里把个人觉得最好理解的一套算法展示出来(其实就是借过来用用。。再次声明,非原创。。原创的大神真的找不着了。。)。

好像这里注释写的不“丰满”,如果有疑问可以一起讨论。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-5-27 16:25:33 | 显示全部楼层
试了一下,学习了。
发现如果是非唯一解的话,会输出多个解法,这个是怎么实现的属实没看懂
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-29 12:42:42 | 显示全部楼层
因为回溯算法,是深度遍历优先,pop函数主要是在存在代码中的递归下面,用来剪枝的。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-30 23:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表