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程序员易犯的错误
Dec 15 Python
Python2/3中urllib库的一些常见用法
Dec 19 Python
python安装教程
Feb 28 Python
Matplotlib 生成不同大小的subplots实例
May 25 Python
Python中 map()函数的用法详解
Jul 10 Python
使用Python实现企业微信的自动打卡功能
Apr 30 Python
基于Django统计博客文章阅读量
Oct 29 Python
Python 解析pymysql模块操作数据库的方法
Feb 18 Python
Python特殊属性property原理及使用方法解析
Oct 09 Python
Python 爬虫批量爬取网页图片保存到本地的实现代码
Dec 24 Python
python自动化发送邮件实例讲解
Jan 04 Python
python 如何读、写、解析CSV文件
Mar 03 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
windows下开发并编译PHP扩展的方法
2011/03/18 PHP
php实现多城市切换特效
2015/08/09 PHP
php通过header发送自定义数据方法
2018/01/18 PHP
JS关键字变色实现思路及代码
2013/02/21 Javascript
jQuery消息提示框插件Tipso
2015/05/04 Javascript
手机开发必备技巧:javascript及CSS功能代码分享
2015/05/25 Javascript
实例解析jQuery中proxy()函数的用法
2016/05/24 Javascript
jQuery实现指定区域外单击关闭指定层的方法【经典】
2016/06/22 Javascript
Javascript中indexOf()和lastIndexOf应用方法实例
2016/08/24 Javascript
AngularJS bootstrap启动详解及实例代码
2016/09/14 Javascript
详解前端路由实现与react-router使用姿势
2017/08/07 Javascript
微信小程序实现分享朋友圈的图片功能示例
2019/01/18 Javascript
微信小程序结合mock.js实现后台模拟及调试
2019/03/28 Javascript
JS array数组检测方式解析
2020/05/19 Javascript
[48:48]2014 DOTA2国际邀请赛中国区预选赛 SPD-GAMING VS Dream TIME
2014/05/21 DOTA
举例讲解Python设计模式编程中对抽象工厂模式的运用
2016/03/02 Python
python生成随机图形验证码详解
2017/11/08 Python
python 对类的成员函数开启线程的方法
2019/01/22 Python
python opencv 图像拼接的实现方法
2019/06/27 Python
Python 内存管理机制全面分析
2021/01/16 Python
Python+MySQL随机试卷及答案生成程序的示例代码
2021/02/01 Python
CSS3 制作绽放的莲花采用效果叠加实现
2013/01/31 HTML / CSS
阿里巴巴国际站:Alibaba.com
2016/07/21 全球购物
大学毕业生自我鉴定
2013/11/05 职场文书
园林施工员岗位职责
2013/12/11 职场文书
2014年消防工作实施方案
2014/02/20 职场文书
《四季》教学反思
2014/04/08 职场文书
反四风个人对照检查材料思想汇报
2014/09/25 职场文书
幼儿园法制宣传日活动总结
2014/11/01 职场文书
2014年安全员工作总结
2014/11/13 职场文书
考试作弊检讨书范文
2015/01/27 职场文书
2015年国际护士节演讲稿
2015/03/18 职场文书
行为习惯主题班会
2015/08/14 职场文书
SQL Server中常用截取字符串函数介绍
2022/03/16 SQL Server
python处理json数据文件
2022/04/11 Python
MySQL数据管理操作示例讲解
2022/12/24 MySQL