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的Django框架加载模版的方式
Jul 20 Python
Python中几种属性访问的区别与用法详解
Oct 10 Python
python中join()方法介绍
Oct 11 Python
10 行Python 代码实现 AI 目标检测技术【推荐】
Jun 14 Python
选择python进行数据分析的理由和优势
Jun 25 Python
详解使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件
Aug 23 Python
python实现简单井字棋小游戏
Mar 05 Python
Python Handler处理器和自定义Opener原理详解
Mar 05 Python
4行Python代码生成图像验证码(2种)
Apr 07 Python
Python 分布式缓存之Reids数据类型操作详解
Jun 24 Python
python简单实现插入排序实例代码
Dec 16 Python
基于Python的接口自动化读写excel文件的方法
Jan 15 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/12/21 PHP
Laravel获取当前请求的控制器和方法以及中间件的例子
2019/10/11 PHP
dojo学习第二天 ajax异步请求之绑定列表
2011/08/29 Javascript
ff chrome和ie下全局动态定位的异同及全局高度的取法
2014/06/30 Javascript
JsRender for object语法简介
2014/10/31 Javascript
AngularJS模块管理问题的非常规处理方法
2015/04/29 Javascript
BootStrap入门教程(一)之可视化布局
2016/09/19 Javascript
JS用斜率判断鼠标进入DIV四个方向的方法
2016/11/07 Javascript
Vue学习之路之登录注册实例代码
2017/07/06 Javascript
Node.js实现发送邮件功能
2017/11/06 Javascript
基于js中style.width与offsetWidth的区别(详解)
2017/11/12 Javascript
jquery动态添加带有样式的HTML标签元素方法
2018/02/24 jQuery
vue权限问题的完美解决方案
2019/05/08 Javascript
JS快速实现简单计算器
2020/04/08 Javascript
jQuery 常用特效实例小结【显示与隐藏、淡入淡出、滑动、动画等】
2020/05/19 jQuery
vue 动态设置img的src地址无效,npm run build 后找不到文件的解决
2020/07/26 Javascript
[42:20]Winstrike vs VGJ.S 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
用实例分析Python中method的参数传递过程
2015/04/02 Python
简单学习Python time模块
2016/04/29 Python
Python2与python3中 for 循环语句基础与实例分析
2017/11/20 Python
详解Python核心对象类型字符串
2018/02/11 Python
python 动态迁移solr数据过程解析
2019/09/04 Python
Python打包工具PyInstaller的安装与pycharm配置支持PyInstaller详细方法
2020/02/27 Python
Python selenium页面加载慢超时的解决方案
2020/03/18 Python
python实现图像高斯金字塔的示例代码
2020/12/11 Python
利用css3径向渐变做一张优惠券的示例
2018/03/22 HTML / CSS
佳能法国商店:Canon法国
2019/02/14 全球购物
幼儿教师个人求职信范文
2013/09/21 职场文书
《太阳》教学反思
2014/02/21 职场文书
机关办公室岗位职责
2014/04/16 职场文书
英语演讲稿3分钟
2014/04/29 职场文书
2015入党自传格式范文
2015/06/26 职场文书
go语言map与string的相互转换的实现
2021/04/07 Golang
分享mysql的current_timestamp小坑及解决
2021/11/27 MySQL
Win11无法访问设备和打印机 如何解决页面空白
2022/04/09 数码科技
分析SQL窗口函数之取值窗口函数
2022/04/21 Oracle