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简单的函数定义和用法实例
May 07 Python
在Python中使用next()方法操作文件的教程
May 24 Python
详解Django框架中的视图级缓存
Jul 23 Python
Python 如何访问外围作用域中的变量
Sep 11 Python
Python批量发送post请求的实现代码
May 05 Python
python smtplib模块自动收发邮件功能(一)
May 22 Python
Mac下Anaconda的安装和使用教程
Nov 29 Python
python f-string式格式化听语音流程讲解
Jun 18 Python
python GUI库图形界面开发之PyQt5开发环境配置与基础使用
Feb 25 Python
Python使用Selenium模拟浏览器自动操作功能
Sep 08 Python
解决tensorflow模型压缩的问题_踩坑无数,总算搞定
Mar 02 Python
Python包argparse模块常用方法
Jun 04 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
frename PHP 灵活文件命名函数 frename
2009/09/09 PHP
php设计模式 Factory(工厂模式)
2011/06/26 PHP
PHP 实现页面静态化的几种方法
2017/07/23 PHP
几个比较经典常用的jQuery小技巧
2010/03/01 Javascript
javascript 基础篇1 什么是js 建立第一个js程序
2012/03/14 Javascript
JavaScript判断密码强度(自写代码)
2013/09/06 Javascript
自己编写的类似JS的trim方法
2013/10/09 Javascript
javascript关于继承解析
2016/05/10 Javascript
AngularJS入门教程之Cookies读写操作示例
2016/11/02 Javascript
ES6概念 Symbol.keyFor()方法
2016/12/25 Javascript
jQuery实现拖动效果的实例代码
2017/06/25 jQuery
JavaScript数据结构之单链表和循环链表
2017/11/28 Javascript
jQuery实现的简单图片轮播效果完整示例
2018/02/08 jQuery
详解Axios统一错误处理与后置
2018/09/26 Javascript
JavaScript强制类型转换和隐式类型转换操作示例
2019/05/01 Javascript
vue+导航锚点联动-滚动监听和点击平滑滚动跳转实例
2019/11/13 Javascript
js表达式与运算符简单操作示例
2020/02/15 Javascript
[08:47]2018国际邀请赛 OG战队举杯时刻
2018/08/29 DOTA
Python中super()函数简介及用法分享
2016/07/11 Python
python爬取w3shcool的JQuery课程并且保存到本地
2017/04/06 Python
[原创]教女朋友学Python3(二)简单的输入输出及内置函数查看
2017/11/30 Python
python使用os.listdir和os.walk获得文件的路径的方法
2017/12/16 Python
python散点图实例之随机漫步
2018/08/27 Python
Python增强赋值和共享引用注意事项小结
2019/05/28 Python
face++与python实现人脸识别签到(考勤)功能
2019/08/28 Python
python在OpenCV里实现投影变换效果
2019/08/30 Python
springboot配置文件抽离 git管理统 配置中心详解
2019/09/02 Python
超实用的 30 段 Python 案例
2019/10/10 Python
基于torch.where和布尔索引的速度比较
2020/01/02 Python
查看keras的默认backend实现方式
2020/06/19 Python
css3闪亮进度条效果实现思路及代码
2013/04/17 HTML / CSS
销售文员的岗位职责
2013/11/20 职场文书
医德医风演讲稿
2014/05/20 职场文书
2015年实习单位评语
2015/03/25 职场文书
加薪申请书应该这样写!
2019/07/04 职场文书
python scrapy简单模拟登录的代码分析
2021/07/21 Python