python3.6数独问题的解决


Posted in Python onJanuary 21, 2019

算法比较暴力,直接用穷举的方式一个一个去试,所以程序运行时间会比较长,运行时间视数独而定。
不过从一开始到运行成功,整个过程却是一波三折,设计算法就花了不少时间,然后就是不断地去调试,找bug。刚开始的时候为了省事直接在sudoku类中递归调用blank,但是老哥还是too young too simple,sometimes navie,计算量实在是太大了,后面编译器直接抛出 “RecursionError: maximum recursion depth exceeded while calling a Python object” 超过最大递归深度的错误。在把递归深度改到100000之后,又出现了堆栈溢出问题。当然,解决办法也是相当地暴力:把递归放入while循环中,一旦符合条件就直接exit(0),整个程序直接gg,然后退出结束。
当然,算法还可以再优化一下,可以不用那么暴力,先列出可能的值然后再填入,这样可以大大缩小整个程序的运行时间,但是……懒得优化了,就这样吧,又不是不能用(笑~)。

运行结果:

python3.6数独问题的解决

再试一个其他的数独:

python3.6数独问题的解决

这回就快得多了,11秒就完成了,比第一个数独不知高到哪里去了

代码如下所示:

import copy
import time

t1=time.time()
origin = [[8, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 3, 6, 0, 0, 0, 0, 0],
  [0, 7, 0, 0, 9, 0, 2, 0, 0],
  [0, 5, 0, 0, 0, 7, 0, 0, 0],
  [0, 0, 0, 0, 4, 5, 7, 0, 0],
  [0, 0, 0, 1, 0, 0, 0, 3, 0],
  [0, 0, 1, 0, 0, 0, 0, 6, 8],
  [0, 0, 8, 5, 0, 0, 0, 1, 0],
  [0, 9, 0, 0, 0, 0, 4, 0, 0]]

class sudoku:
 def debug(self): # 调试
 for list in origin:
  print(list)
 print("\n")

 def check_repetition(self,list):#判断表中是否有重复值,0除外
 flag=0
 for i in range(1,10):
  if list.count(i)>=2:
  return 1
  else:
  flag=flag+1
 if flag==9:
  return 0

 def check_row(self,row):#检测横向是否有重复值,无则为返回0,有则返回1
 list = origin[row] # 横向
 r1 = self.check_repetition(list)
 if r1 == 0:
  return 0
 else :
  return 1

 def check_column(self,column):#检测纵向是否重复值,无则为返回0,有则返回1
 list = [] # 纵向
 for num in origin:
  list.append(num[column])
 r2 = self.check_repetition(list)
 if r2==0:
  return 0
 else:
  return 1

 def check_square(self,x,y):#检测九宫格是否有重复值,无则为返回0,有则返回1
 x,y=y,x
 if x>=9 or y>=9:
  return
 square = []#九宫格
 for i in range(0+y//3*3, 3+y//3*3):
  for j in range(0+x//3*3, 3+x//3*3):
  square.append(origin[i][j])
 r3 = self.check_repetition(square)
 if r3==0:
  return 0
 else:
  return 1

 def check(self,x,y):#检测是否有重复值,无则为0,有则不为0
 r1 = self.check_row(x)
 r2 = self.check_column(y)
 r3 = self.check_square(x, y)
 result=r1+r2+r3
 return result

 def get_next(self): # 获得下一个空值,返回row,column值
 i = 0
 for list in origin:
  try: # 当0不在列表中时,跳过
  column = list.index(0)
  row = origin.index(list)
  res = (row, column)
  return res
  except ValueError:
  i = i + 1
  if i == 9:
   t2=time.time()
   print("总用时={}".format(t2 - t1))
   exit(0)

 def poi(self,row, column): # 位置修正
 if row == 0 and column == -1:
  return
 if row == 8 and column == 9:
  return
 if column == -1:
  column = 8
  row = row - 1
 if column == 9:
  column = 0
  row = row - 1
 return (row, column)

 def get_last(self,row, column):
 origin[row].insert(column, 0)
 origin[row].pop(column + 1)
 column = column - 1 # 获得上一个已填值的行、列位置
 row, column = self.poi(row, column)#位置修正
 r = origin[row][column] * compare[row][column]
 while r != 0:
  column = column - 1
  row, column = self.poi(row, column)
  r = origin[row][column] * compare[row][column]
 return (row, column)

 def blank(self):
 try:
  row,column=self.get_next()
 except TypeError:#已填完
  exit(0)
 j=0
 flag=0
 for i in range(1,10):
  origin[row].insert(column,i)
  origin[row].pop(column+1)
  self.debug()
  r = self.check(row, column)
  if r==0:#无重复值
  return
  else:
  j = j + 1
  if j==9:
   flag=1
   break
 if flag==1:
  row, column = self.get_last(row, column)
  value=origin[row][column]
  self.debug()
  while value == 9:
  row, column = self.get_last(row, column)
  value = origin[row][column]
  self.debug()
  while value<9:
  for k in range(value+1,10):
   origin[row].insert(column, k)
   origin[row].pop(column + 1)
   self.debug()
   r=self.check(row,column)
   if r!=0:#有重复
   if k==9:
    row, column = self.get_last(row, column)
    value=origin[row][column]
    self.debug()
    while value==9:
    row, column = self.get_last(row, column)
    value = origin[row][column]
    self.debug()
    break
   else:
   return

if __name__=="__main__":
 compare = copy.deepcopy(origin)
 sudoku = sudoku()
 while 1:
 sudoku.blank()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python list转dict示例分享
Jan 28 Python
Linux中安装Python的交互式解释器IPython的教程
Jun 13 Python
基于Python的文件类型和字符串详解
Dec 21 Python
Python实现基于PIL和tesseract的验证码识别功能示例
Jul 11 Python
详解10个可以快速用Python进行数据分析的小技巧
Jun 24 Python
关于pycharm中pip版本10.0无法使用的解决办法
Oct 10 Python
Python图像处理库PIL的ImageFont模块使用介绍
Feb 26 Python
在python中使用pymysql往mysql数据库中插入(insert)数据实例
Mar 02 Python
python和js交互调用的方法
Jun 23 Python
Pycharm自动添加文件头注释和函数注释参数的方法
Oct 23 Python
Python实现我的世界小游戏源代码
Mar 02 Python
python 如何用terminal输入参数
May 25 Python
解决python给列表里添加字典时被最后一个覆盖的问题
Jan 21 #Python
对python列表里的字典元素去重方法详解
Jan 21 #Python
在Python中字典根据多项规则排序的方法
Jan 21 #Python
详解opencv Python特征检测及K-最近邻匹配
Jan 21 #Python
pycharm远程开发项目的实现步骤
Jan 20 #Python
对python中类的继承与方法重写介绍
Jan 20 #Python
python 格式化输出百分号的方法
Jan 20 #Python
You might like
PHP面向对象之后期静态绑定功能介绍
2015/05/18 PHP
php实现微信企业付款到个人零钱功能
2018/10/09 PHP
javascript 动态生成私有变量访问器
2009/12/06 Javascript
jQuery 表格插件整理
2010/04/27 Javascript
基于jquery的loading 加载提示效果实现代码
2011/09/01 Javascript
JavaScript用Number方法实现string转int
2014/05/13 Javascript
jQuery中bind()方法用法实例
2015/01/19 Javascript
JS实现的页面自定义滚动条效果
2015/10/26 Javascript
JQuery ztree 异步加载实例讲解
2016/02/25 Javascript
详谈$.data()的用法和作用
2017/02/13 Javascript
js转换对象为xml
2017/02/17 Javascript
纯JS实现轮播图
2017/02/22 Javascript
nodejs接入阿里大鱼短信验证码的方法
2017/07/10 NodeJs
简单实现js轮播图效果
2017/07/14 Javascript
深入理解移动前端开发之viewport
2018/10/19 Javascript
一篇文章,教你学会Vue CLI 插件开发
2019/04/17 Javascript
vue2.0自定义指令示例代码详解
2019/04/25 Javascript
js神秘的电报密码 哈弗曼编码实现
2019/09/10 Javascript
基于javascript原生判断DOM是否加载完毕
2020/10/14 Javascript
vue-cli4使用全局less文件中的变量配置操作
2020/10/21 Javascript
python中实现定制类的特殊方法总结
2014/09/28 Python
Python使用PIL库实现验证码图片的方法
2016/03/11 Python
酷! 程序员用Python带你玩转冲顶大会
2018/01/17 Python
python中对数据进行各种排序的方法
2019/07/02 Python
Python中typing模块与类型注解的使用方法
2019/08/05 Python
Python如何测试stdout输出
2020/08/10 Python
关于pycharm 切换 python3.9 报错 ‘HTMLParser‘ object has no attribute ‘unescape‘ 的问题
2020/11/24 Python
手工制作的男士奢华英国鞋和服装之家:Goodwin Smith
2019/06/21 全球购物
华为慧通面试题
2012/09/11 面试题
Laravel的加密解密与哈希实例讲解
2021/03/24 PHP
三下乡活动方案
2014/01/31 职场文书
团队口号大全
2014/06/06 职场文书
2014机关党员干部“正风肃纪”思想汇报
2014/09/15 职场文书
2014年监理工作总结范文
2014/11/17 职场文书
Python下opencv使用hough变换检测直线与圆
2021/06/18 Python
动画电影《擅长捉弄人的高木同学》6月10日上映!
2022/03/20 日漫