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的__builtin__模块中的一些要点知识
May 02 Python
Python 关于反射和类的特殊成员方法
Sep 14 Python
python中装饰器级连的使用方法示例
Sep 29 Python
解决python3中解压zip文件是文件名乱码的问题
Mar 22 Python
解决phantomjs截图失败,phantom.exit位置的问题
May 17 Python
python自动结束mysql慢查询会话的实例代码
Oct 27 Python
详解Django admin高级用法
Nov 06 Python
matplotlib.pyplot画图并导出保存的实例
Dec 07 Python
Pytorch Tensor基本数学运算详解
Dec 30 Python
Python文件时间操作步骤代码详解
Apr 13 Python
python爬虫如何解决图片验证码
Feb 14 Python
关于Python中进度条的六个实用技巧分享
Apr 05 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中如何直接执行SHELL
2013/06/28 PHP
php 将json格式数据转换成数组的方法
2018/08/21 PHP
ThinkPHP框架整合微信支付之刷卡模式图文详解
2019/04/10 PHP
在次封装easyui-Dialog插件实现代码
2010/11/14 Javascript
jquery 快速回到页首的方法
2013/12/05 Javascript
45个JavaScript编程注意事项、技巧大全
2015/02/11 Javascript
jquery中radio checked问题
2015/03/16 Javascript
JS动态添加iframe的代码
2015/09/14 Javascript
js方法数据验证的简单实例
2016/09/17 Javascript
利用jQuery插件imgAreaSelect实现图片上传裁剪(放大缩小)
2016/12/02 Javascript
ES6中Proxy代理用法实例浅析
2017/04/06 Javascript
JavaScript中最常用的10种代码简写技巧总结
2017/06/28 Javascript
JavaScript中document.referrer的用法详解
2017/07/04 Javascript
VUE2.0+Element-UI+Echarts封装的组件实例
2018/03/02 Javascript
iview实现select tree树形下拉框的示例代码
2018/12/21 Javascript
微信小程序实现轨迹回放的示例代码
2019/12/13 Javascript
详解钉钉小程序组件之自定义模态框(弹窗封装实现)
2020/03/07 Javascript
Electron整合React使用搭建开发环境的步骤详解
2020/06/07 Javascript
vue将data恢复到初始状态 &amp;&amp; 重新渲染组件实例
2020/09/04 Javascript
vue3使用vue-count-to组件的实现
2020/12/25 Vue.js
Python入门Anaconda和Pycharm的安装和配置详解
2019/07/16 Python
tensorflow之变量初始化(tf.Variable)使用详解
2020/02/06 Python
Keras自动下载的数据集/模型存放位置介绍
2020/06/19 Python
CSS3实现同时执行倾斜和旋转的动画效果
2016/10/27 HTML / CSS
html5实现canvas阴影效果示例
2014/05/07 HTML / CSS
J2ee常用的设计模式?说明工厂模式
2015/05/21 面试题
精彩的大学生自我评价
2013/11/17 职场文书
教师旷工检讨书
2014/01/18 职场文书
小学教师师德感言
2014/02/10 职场文书
消防应急演练方案
2014/02/12 职场文书
境外导游求职信
2014/02/27 职场文书
我爱幼儿园演讲稿
2014/09/11 职场文书
国土资源局开展党的群众路线教育实践活动整改措施
2014/09/26 职场文书
违反单位工作制度检讨书
2014/10/25 职场文书
2016大一新生军训感言
2015/12/08 职场文书
Java9新特性之Module模块化编程示例演绎
2022/03/16 Java/Android