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编程实现二叉树及七种遍历方法详解
Jun 02 Python
浅谈flask源码之请求过程
Jul 26 Python
Python实现繁体中文与简体中文相互转换的方法示例
Dec 18 Python
djang常用查询SQL语句的使用代码
Feb 15 Python
Python实现监控Nginx配置文件的不同并发送邮件报警功能示例
Feb 26 Python
python实现坦克大战游戏 附详细注释
Mar 27 Python
python 实现在一张图中绘制一个小的子图方法
Jul 07 Python
Python实现生成密码字典的方法示例
Sep 02 Python
深入浅析Python 中的sklearn模型选择
Oct 12 Python
Python列表list常用内建函数实例小结
Oct 22 Python
python GUI库图形界面开发之PyQt5工具栏控件QToolBar的详细使用方法与实例
Feb 28 Python
Python实现信息轰炸工具(再也不怕说不过别人了)
Jun 11 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
第十二节 类的自动加载 [12]
2006/10/09 PHP
PHP多文件上传类实例
2015/03/07 PHP
php检测图片主要颜色的方法
2015/07/01 PHP
PHP基于MySQLI函数封装的数据库连接工具类【定义与用法】
2017/08/11 PHP
事件绑定之小测试  onclick &amp;&amp; addEventListener
2011/07/31 Javascript
jquery实现用户打分评分特效
2015/05/28 Javascript
JavaScript观察者模式(经典)
2015/12/09 Javascript
JavaScript操作class和style样式代码详解
2016/02/13 Javascript
javacript获取当前屏幕大小
2016/06/04 Javascript
使用 jQuery.ajax 上传带文件的表单遇到的问题
2016/10/31 Javascript
Bootstrap基本组件学习笔记之缩略图(13)
2016/12/08 Javascript
codeMirror插件使用讲解
2017/01/16 Javascript
Vue.js 2.0 移动端拍照压缩图片预览及上传实例
2017/04/27 Javascript
解决JS外部文件中文注释出现乱码问题
2017/07/09 Javascript
解决JavaScript layui 下拉框不显示的问题
2018/08/14 Javascript
JavaScript实现联动菜单特效
2020/01/07 Javascript
JS 数组基本用法入门示例解析
2020/01/16 Javascript
解决vue bus.$emit触发第一次$on监听不到问题
2020/07/28 Javascript
在vant中使用时间选择器和popup弹出层的操作
2020/11/04 Javascript
python实现数通设备tftp备份配置文件示例
2014/04/02 Python
Python实现的百度站长自动URL提交小工具
2014/06/27 Python
python生成日历实例解析
2014/08/21 Python
pyqt5 获取显示器的分辨率的方法
2019/06/18 Python
python中字符串数组逆序排列方法总结
2019/06/23 Python
Python在centos7.6上安装python3.9的详细教程(默认python版本为2.7.5)
2020/10/15 Python
python3.9.1环境安装的方法(图文)
2021/02/02 Python
整理HTML5中支持的URL编码与字符编码
2016/02/23 HTML / CSS
新西兰演唱会和体育门票网站:Ticketmaster新西兰
2017/10/07 全球购物
娱乐地球:Entertainment Earth
2020/01/08 全球购物
公司行政主管岗位职责
2015/04/09 职场文书
活动总结模板大全
2015/05/11 职场文书
我的1919观后感
2015/06/03 职场文书
幼儿园开学家长寄语(2016春季)
2015/12/03 职场文书
2016年感恩节活动总结大全
2016/04/01 职场文书
详解NodeJS模块化
2021/06/15 NodeJs
攻略丨滑雪究竟该选哪款对讲机?
2022/02/18 无线电