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使用nntp读取新闻组内容的方法
May 08 Python
Python中的数据对象持久化存储模块pickle的使用示例
Mar 03 Python
Python 模板引擎的注入问题分析
Jan 01 Python
Python 自动化表单提交实例代码
Jun 08 Python
使用python语言,比较两个字符串是否相同的实例
Jun 29 Python
django页面跳转问题及注意事项
Jul 18 Python
详解python 利用echarts画地图(热力图)(世界地图,省市地图,区县地图)
Aug 06 Python
python numpy 矩阵堆叠实例
Jan 17 Python
基于python 凸包问题的解决
Apr 16 Python
Python如何使用正则表达式爬取京东商品信息
Jun 01 Python
python语音识别指南终极版(有这一篇足矣)
Sep 09 Python
python 元组和列表的区别
Dec 30 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/03/27 PHP
BOOM vs RR BO3 第一场2.13
2021/03/10 DOTA
JavaScript 事件参考手册
2008/12/24 Javascript
javascript 跳转代码集合
2009/12/03 Javascript
JS中 用户登录系统的解决办法
2013/04/15 Javascript
jQuery 取值、赋值的基本方法整理
2014/03/31 Javascript
JavaScript中的时间处理小结
2016/02/24 Javascript
一步一步封装自己的HtmlHelper组件BootstrapHelper(二)
2016/09/14 Javascript
通过sails和阿里大于实现短信验证
2017/01/04 Javascript
JQuery ZTree使用方法详解
2017/01/07 Javascript
javascript阻止事件冒泡和浏览器的默认行为
2017/01/21 Javascript
JS表单提交验证、input(type=number) 去三角 刷新验证码
2017/06/21 Javascript
jQuery实现注册会员时密码强度提示信息功能示例
2017/09/05 jQuery
原生js的ajax和解决跨域的jsonp(实例讲解)
2017/10/16 Javascript
vue使用iframe嵌入网页的示例代码
2020/06/09 Javascript
Node.js中Koa2在控制台输出请求日志的方法示例
2019/05/02 Javascript
解决layui table表单提示数据接口请求异常的问题
2019/09/24 Javascript
[01:09:13]DOTA2-DPC中国联赛 正赛 CDEC vs XG BO3 第三场 1月19日
2021/03/11 DOTA
python实现web方式logview的方法
2015/08/10 Python
对python sklearn one-hot编码详解
2018/07/10 Python
详解python中eval函数的作用
2019/10/22 Python
python实现简单日志记录库glog的使用
2019/12/13 Python
python神经网络编程实现手写数字识别
2020/05/27 Python
PyCharm2019 安装和配置教程详解附激活码
2020/07/31 Python
Otel.com:折扣酒店预订
2017/08/24 全球购物
Currentbody西班牙:美容仪专家
2019/09/28 全球购物
新浪网技术部笔试题
2016/08/26 面试题
C/C++程序员常见面试题一
2012/12/08 面试题
计算机毕业大学生推荐信
2013/12/01 职场文书
九一八事变纪念日演讲稿
2014/09/14 职场文书
2014年客服工作总结与计划
2014/12/09 职场文书
防汛通知
2015/04/25 职场文书
MySQL注入基础练习
2021/05/30 MySQL
Python办公自动化解决world文件批量转换
2021/09/15 Python
Python 的演示平台支持 WSGI 接口的应用
2022/04/20 Python
vscode远程免密登入Linux服务器的配置方法
2022/06/28 Servers