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的web.py框架下的application.py模块
May 02 Python
Django中实现点击图片链接强制直接下载的方法
May 14 Python
python中异常捕获方法详解
Mar 03 Python
python中子类调用父类函数的方法示例
Aug 18 Python
关于Tensorflow中的tf.train.batch函数的使用
Apr 24 Python
Python中pymysql 模块的使用详解
Aug 12 Python
numpy创建单位矩阵和对角矩阵的实例
Nov 29 Python
Docker部署Python爬虫项目的方法步骤
Jan 19 Python
python定义类self用法实例解析
Jan 22 Python
python deque模块简单使用代码实例
Mar 12 Python
python 用opencv实现图像修复和图像金字塔
Nov 27 Python
python实现socket简单通信的示例代码
Apr 13 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读取网页文件内容的实现代码(fopen,curl等)
2011/06/23 PHP
CURL状态码列表(详细)
2013/06/27 PHP
php使用base64加密解密图片示例分享
2014/01/20 PHP
php数组查找函数in_array()、array_search()、array_key_exists()使用实例
2014/04/29 PHP
PHP中基本HTTP认证技巧分析
2015/03/16 PHP
PHP中call_user_func_array回调函数的用法示例
2016/11/26 PHP
jQuery jqgrid 对含特殊字符json 数据的 Java 处理方法
2011/01/01 Javascript
javascript数组去掉重复
2011/05/12 Javascript
跨域传值即主页面与iframe之间互相传值
2013/12/09 Javascript
JS批量修改PS中图层名称的方法
2014/01/26 Javascript
js实现连个数字相加而不是拼接的方法
2014/02/23 Javascript
JavaScript生成随机数的4种自定义函数分享
2015/02/28 Javascript
jQuery实现选中弹出窗口选择框内容后赋值给文本框的方法
2015/11/23 Javascript
一道关于JavaScript变量作用域的面试题
2016/03/08 Javascript
JS实现超简单的汉字转拼音功能示例
2016/12/22 Javascript
JS 使用 window对象的print方法实现分页打印功能
2018/05/16 Javascript
Angular PWA使用的Demo示例
2019/01/31 Javascript
vue使用一些外部插件及样式的配置代码
2019/11/18 Javascript
详解Vue 数据更新了但页面没有更新的 7 种情况汇总及延伸总结
2020/05/28 Javascript
vue axios封装httpjs,接口公用配置拦截操作
2020/08/11 Javascript
python获取网页状态码示例
2014/03/30 Python
Python操作json数据的一个简单例子
2014/04/17 Python
Python并发编程协程(Coroutine)之Gevent详解
2017/12/27 Python
windows环境下tensorflow安装过程详解
2018/03/30 Python
Python使用sorted对字典的key或value排序
2018/11/15 Python
python里dict变成list实例方法
2019/06/26 Python
Python正则表达式匹配日期与时间的方法
2019/07/07 Python
M1芯片安装python3.9.1的实现
2021/02/02 Python
css3教程之倾斜页面
2014/01/27 HTML / CSS
杭州SQL浙江浙大网新恩普软件有限公司
2013/07/27 面试题
大学生社会实践评语
2014/04/25 职场文书
县政府办公室领导班子对照检查材料思想汇报
2014/09/28 职场文书
简历自我评价模板
2015/03/11 职场文书
2016年元旦致辞
2015/08/01 职场文书
2016北大自主招生自荐信模板
2016/01/28 职场文书
动视暴雪取消疫苗禁令 让所有员工返回线下工作
2022/04/03 其他游戏