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备份Mysql脚本
Aug 11 Python
Python fileinput模块使用介绍
Nov 30 Python
简化Python的Django框架代码的一些示例
Apr 20 Python
python fabric使用笔记
May 09 Python
python中实现指定时间调用函数示例代码
Sep 08 Python
python如何为创建大量实例节省内存
Mar 20 Python
Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能示例
May 16 Python
python获取指定字符串中重复模式最高的字符串方法
Jun 29 Python
详解django中url路由配置及渲染方式
Feb 25 Python
Python基础知识点 初识Python.md
May 14 Python
在Python中使用filter去除列表中值为假及空字符串的例子
Nov 18 Python
python字典按照value排序方法
Dec 28 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 setcookie函数的参数说明及其用法
2014/04/20 PHP
详解WordPress中过滤链接与过滤SQL语句的方法
2015/12/18 PHP
PHP+MariaDB数据库操作基本技巧备忘总结
2018/05/21 PHP
php获取微信基础接口凭证Access_token
2018/08/23 PHP
jquery 学习之二 属性相关
2010/11/23 Javascript
初识JQuery 实例一(first)
2011/03/16 Javascript
JavaScript之自定义类型
2012/05/04 Javascript
详解JavaScript函数绑定
2013/08/18 Javascript
addEventListener()第三个参数useCapture (Boolean)详细解析
2013/11/07 Javascript
JavaScript作用域链示例分享
2014/05/27 Javascript
AngularJS学习笔记之TodoMVC的分析
2015/02/22 Javascript
jquery实现可横向和竖向展开的动态下滑菜单效果
2015/08/24 Javascript
[原创]Bootstrap 中下拉菜单修改成鼠标悬停直接显示
2016/04/14 Javascript
vue项目设置scrollTop不起作用(总结)
2018/12/21 Javascript
优化Vue项目编译文件大小的方法步骤
2019/05/27 Javascript
[48:35]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 TNC vs Optic
2018/04/03 DOTA
[01:34:42]NAVI vs EG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
python 文件和路径操作函数小结
2009/11/23 Python
python实现爬虫统计学校BBS男女比例之数据处理(三)
2015/12/31 Python
Python 中开发pattern的string模板(template) 实例详解
2017/04/01 Python
Python学生成绩管理系统简洁版
2020/04/05 Python
Python+tkinter使用40行代码实现计算器功能
2018/01/30 Python
python print出共轭复数的方法详解
2019/06/25 Python
TensorFlow 显存使用机制详解
2020/02/03 Python
在python tkinter界面中添加按钮的实例
2020/03/04 Python
Python字符串及文本模式方法详解
2020/09/10 Python
python字典通过值反查键的实现(简洁写法)
2020/09/30 Python
python openCV自制绘画板
2020/10/27 Python
HTML5+CSS3模仿优酷视频截图功能示例
2017/01/05 HTML / CSS
学生发电厂实习自我鉴定
2013/09/22 职场文书
企业宣传方案
2014/03/04 职场文书
大学生学习2014全国两会心得体会
2014/03/13 职场文书
护士先进个人总结
2015/02/13 职场文书
教师读书活动心得体会
2016/01/14 职场文书
《跨越海峡的生命桥》教学反思
2016/02/18 职场文书
使用Vue3+Vant组件实现App搜索历史记录功能(示例代码)
2021/06/09 Vue.js