如何用python计算数独_用python解决数独
看到了,季以安:用Python解数独[0],写得很详细,我没有全部看完,借用他的思路,我也来试试,回头再去看他怎么弄,特别是递归的实现方式。
先上思路:
'''1.解9*9数独的思路:(1)一个单元格的推理:根据行、列、小矩阵得出该单元格有可能填入的数值的三个列表;求并集,缩小范围,简单的题目好多单元格都能得到唯一值。(2)重复上面这个过程2.实现:(1)复制生成三个新数独(按行、按列、按小矩阵)(2)把上述三个数独每个空单元格内填满’有可能‘的数值(用列表填入)(3)遍历每个空单元格,去找这个单元格分别是三个新数独的哪个位置(是三个列表-求交集)(4)更新原数独,递归更新后的数独(5)我也知道这个程序思路,只能做比较简单的数独,就是练练,写得好会考虑怎么解高等级数独。'''图一:数独就是一个二维列表,用过xlwings操作过excel的很好理解 以下考虑算法的时候就看着这张图就行了
思路确定后,来定一下程序大致的框架:
soduku1 #待求解的数独
soduku2 #复制soduku1,然后遍历空单元格,按行来确定该单元格可能填入哪些值(一个列表),
全算出来后就是一个新数独(思路不断在二维列表和图一之间切换)
soduku3 #和上面一样,按列,基本相同,
soduku4 #按小矩阵,实现需要计算思考
A:def 复制待解数独(soduku1):
# 1.因为soduku1是有用的,不要去修改,所以复制
# 2.soduku2,soduku3的结构是一样的,所有写在一起
# 3.按行生成soduku2很简单,就是单纯的复制soduku1,只不过因为是二维列表,
要用copy.deepcopy(soduku1)才有用,不能soduku2=soduku1[:],更不能
soduku2=soduku1这么粗暴
# 4.按列生成soduku3,复杂一点,这里是框架,先不说
return newsodu
B:def 按待解数独生成小矩阵数独(soduku1):
#这个需要一点观察,还需要一点小学水平算法
return newsodu
C:def 把新生成的三个数组空格全填满(sodu):
#看图方式:cells(0,0)(看图一,这个表示第0行,第0列,即第一个
单元格,后面都采取这样的方式看图)
# soduku2的cells(0,0)会被填入[2,4,5,6],表示按行第一个单元格可能是2,4,5,6
# 全填满无非是循环
# 分别传入参数soduku2,soduku3,soduku4,就会得到三个填满的新数独
return 填满的三个新数独
def 重复算():
调用C:分别传入soduku2,soduku3,soduku4
烂尾了,本来想一步步写思路,没耐心写了,好像也不太有人看,看别人代码有时是很难受的,直接上代码,基本思路注释里还是有的。
'''1.解9*9数独的思路:(1)一个单元格的推理:根据行、列、小矩阵得出该单元格有可能填入的数值的三个列表;求并集,缩小范围,简单的题目好多单元格都能得到唯一值。(2)重复上面这个过程2.实现:(1)复制生成三个新数独(按行、按列、按小矩阵)(2)把上述三个数独每个空单元格内填满’有可能‘的数值(用列表填入)(3)遍历每个空单元格,去找这个单元格分别是三个新数独的哪个位置(是三个列表-求交集),简单的题目这一步就能得到一个唯一值(4)更新原数独,递归更新后的数独(5)我也知道这个程序思路,只能做比较简单的数独,就是练练,写得好会考虑怎么解高等级数独。'''
import copy
import numpy as np
import xlwings as xw
soduku = [[] for i in range(9)]
soduku[0] = ['',8,9,1,'',3,'','','']
soduku[1] = ['',2,7,4,'','',8,'','']
soduku[2] = ['','','',5,2,'','','','']
soduku[3] = ['',7,6,9,'','',5,'',8]
soduku[4] = [8,'',3,6,'',1,2,'','']
soduku[5] = ['',4,5,3,8,7,1,6,'']
soduku[6] = [7,'',8,2,1,4,3,9,5]
soduku[7] = [9,3,1,7,6,5,4,'',2]
soduku[8] = [4,'',2,'','',9,'','',6]
#复制待解数组
#按行直接复制
#按列用要用zip合并转换
def tran_sodu(sodu,col=None):
if col==None:
return copy.deepcopy(soduku)
else:
new_sodu=list(zip(*copy.deepcopy(soduku)))
new_sodu=[list(i) for i in new_sodu]
return new_sodu
#填满空单元格,并为了格式统一好处理,把已知的值,由数值转为列表
def input_none(sodu):
for row in sodu:
row_none = [i for i in range(1,10) if i not in row]
for x in range(len(row)):
if row[x]=="":
row[x]=row_none
else:
row[x]=[row[x]]
return sodu
'''1.按小矩阵复制待解数组,9个小矩阵组成新数独2.用了numpy知识,很好用,但在单个元素的数据类型上有很多坑3.思路:把待解数组reshape成27组,每组3个元素的矩阵A,那么第一个小矩阵就取矩阵A的第1、4、7个元素,依次类推'''
def jvzheng(soduku):
arr = np.array(soduku)
# arr=[list(i) for i in arr.reshape(27,3)]
arr = arr.reshape(27,3).tolist()
for a in arr:
for b in range(3):
if a[b]!="":
a[b]=int(a[b])
newSodu=[[] for i in range(9)]
j=0
for i in range(9):
newSodu[i]=arr[j]+arr[j+3]+arr[j+6]
j=j+1
if j>=3 and j%3==0:
j=j+6
return newSodu
'''1、开始解数独后,遍历每个空单元格,去找该单元格对应到三个新数独的单元格时:(1)如果待解数独的单元格是soduku-cells(j,k),那么对应过去,按行的当然也是:按行-cells(j,k),按列的也很简单,相反,是:按列-cells(k,j)(2)按小矩阵的难解一点,就是下面的函数,和jvzheng()的主要代码一样,就是再转置一次,就转回去了,效果是:按小矩阵-cells(j,k)(3)按行-cells(j,k),按列-cells(k,j),按小矩阵-cells(j,k)这三个列表就能求交集了,最希望得到的是一个唯一值'''
def jvzheng2(soduku):
arr = np.array(soduku)
# arr=[list(i) for i in arr.reshape(27,3)]
arr=arr.reshape(27,3).tolist()
newSodu=[[] for i in range(9)]
j=0
for i in range(9):
newSodu[i]=arr[j]+arr[j+3]+arr[j+6]
j=j+1
if j>=3 and j%3==0:
j=j+6
return newSodu
import sys
sys.setrecursionlimit(50000) #这里设置大一些
'''1.递归函数,重复2.基本原理在jvzheng2()上面写了'''
def fin(s):
global cc,rr,jz,jz2
rr=input_none(tran_sodu(soduku)) # 按行填满各空格有可能的缺失值
cc=input_none(tran_sodu(soduku,1)) #按列
jz=input_none(jvzheng(soduku)) #按小矩阵
jz2=jvzheng2(jz)
'''规则一:行、列、小矩阵求交集遍历待解数独的每个空单元格,找到该单元格在rr,cc,jz2中的位置,并求交集当这个交集只有一个值时,就填入待解数独中'''
for j in range(9):
for k in range(9):
if s[j][k]=="":
'''下面的判断是numpy数据类型的一个坑,numpy会将[9]这样的单个数值的列表直接处理成数字9,这在算到最后一步时,代码就会跳错识了,因此加了判断,核心代码是else下面的那名就够了。'''
if isinstance(jz2[j][k],int):
target=set(rr[j][k])&set(cc[k][j])
else:
target=set(rr[j][k])&set(cc[k][j])&set(jz2[j][k])
if len(target)==1:
s[j][k]=list(target)[0]
'''规则二:如[8,4,[3,7,9],6,[1,5],[1,3,5],[1,5,9],[1,3,9],2]第三个[3,7,9],虽然有三个可能值,但观察一行,‘7’,在其他位置都没有出现过,因此第三位置肯定是‘7’'''
'''规则三……规则越多,能解的难题越多,达到通用,就不会出现“递归深度不够”,”栈溢出“等问题,数独知识有限,写不下去了,只能解简单数独。'''
#每递归一次,待解数独就会更新
#把待解数独摊开,如果没有一个空值,那说明解完了
if "" not in np.array(s).reshape(1,81)[0].tolist():
# if "" not in s[3]:
return s
else:
fin(s)
return s
def main():
fin(soduku)
print(soduku)
xw.Range("K1").value = soduku
if __name__ == '__main__':
main()
解出来了,因为例子实在太简单了,稍微复杂一点就出现“栈溢出”了。
因为规则只有一条,无论怎么递归都得不到答案。
如何用python计算数独_用python解决数独相关推荐
- 用python计算圆周率_用python计算圆周率π
原博文 2020-03-22 15:32 − 用python计算圆周率π 一.要求 1.要起义能计算到圆周率后面越多位越好. 2.用进度条显示计算的进度,能给出越多种进度条越好. 3.要求给出圆周率π ...
- 如何用python计算年龄_用Python写一个能算出自己年龄的小程序
用Python写一个能算出自己年龄的小程序. 其实我连我今年多少岁都不知道,最近看到了python的datetime库里面有很多好用的方法,于是就写了这样一个程序作为练习,然后又写了这样一篇文章来梳理 ...
- python计算条件概率_用Python实现贝叶斯定理(附代码)
写作说明 上一期我们讲了贝叶斯分类器,其中有很多的概率基础知识和贝叶斯定理.但是讲解的很没有重点,前半部分讲的是贝叶斯基础知识,最后很突兀的插进来一个文本分析-贝叶斯分类器.很多童鞋看到很累.其实上一 ...
- python计算圆周率_用python计算圆周率Π
一.要求: 1.计算到圆周率后面越多位越好. 2.用进度条显示计算的进度. 3.要求给出圆周率Π的具体计算方法和解释. 二.算法: 1.拉马努金公式: 2.高斯-勒让德公式: 设置初始值: 反复执行以 ...
- python计算信息增益_利用Python提取ABAQUS的计算结果(ODB)信息、体积、应变等变化(一)...
00 实例模型 一个金属长方体,我们需要对其做拉伸的加载约束示意图如图1,并在完成后采用Python命令流读取参考点的位移.体积.应变随加载时间的变化情况. 图1 金属长方体约束加载示意图 01 Py ...
- python计算协方差_在Python中计算协方差
要计算协方差,您需要类似下面这样的内容,它有一个嵌套循环,遍历每个列表,并使用协方差公式累积协方差.在# let's get the mean of `X` (add all the vals in ...
- python计算坡度_基于python实现利用DEM数据计算坡度、坡向
1.Python的地形三维可视化--简介Matplotlib和gdal https://blog.csdn.net/allenlu2008/article/details/51880333 2.Pyc ...
- python计算三角函数_使用Python三角函数公式计算三角形的夹角案例
使用Python三角函数公式计算三角形的夹角案例 题目内容: 对于三角形,三边长分别为a, b, c,给定a和b之间的夹角C,则有:.编写程序,使得输入三角形的边a, b, c,可求得夹角C(角度值) ...
- python计算差商_用Python求函数的差商
"某人"已经回答了您的问题,但您(以及未来的读者)可能会发现这些补充信息很有用.在 要获得导数的精确近似值,需要使h相当小.但是,如果将其设置得太小,那么实际上会由于Python浮 ...
- python计算微积分_用Python学微积分---函数
一.什么是函数? 广义上说下面这个就叫函数,因为每当我们向机器提供豆子,这台机器便会输出豆浆. 所有输入的集合(集合的本质特点:无序重合)称为定义域(domain),其所有可能输出的集合称为值域(ra ...
最新文章
- Spring系列之Spring框架和SpringAOP集成过程分析(十)
- vue商城项目开发:axios发送请求及列表数据展示
- 从ca提取keystore_从keystore(jks)文件中提取私钥
- Linux学习笔记8
- connect: Address is invalid on local machine or port is not valid on remote
- linux 从一台服务器向另台服务器复制文件
- Rpc远程调用框架的设计与实现(2)
- 找mysql软件的配置文件_mysql 查看当前使用的配置文件my.cnf的方法
- spring整合quartz框架
- eclipse的安装与环境配置
- 微信搜索,不一样的搜索?
- android手机内存其他文件夹里,别再胡乱清理手机内存了,1秒清空这些文件夹,手机瞬间腾出50G...
- 4G工业路由器要点介绍
- Outperform
- 业务流程(学习笔记)
- 计算机硬件英语单词 m.jb51.net,计算机硬件英汉对照表
- 民事诉讼法知识点详细版
- 深圳云计算培训:关于云计算和云应用,如何入门学习?
- 关于DIV中display属性误区以及牵扯出来的两个问题
- html背景颜色中药制剂,中药制剂