python 数独_python 实现 数独 解法 (穷举法)
3.[文件]
进一步优化代码,性能提高50% ~ 7KB
下载(29)
# -*- coding: utf-8 -*-
'''
Created on 2012-10-5
@author: Administrator
'''
from collections import defaultdict
import itertools
import time
import gc
import operator
import profile
gc.disable()
a = [
[ 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, 6, 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 ]
# 0, 1, 2, 3,|4, 5, 6,|7, 8
]
#a = [
# [ 0, 7, 0, 0, 0, 0, 0, 0, 0], #0
# [ 5, 0, 3, 0, 0, 6, 0, 0, 0], #1
# [ 0, 6, 2, 0, 8, 0, 7, 0, 0], #2
# #
# [ 0, 0, 0, 3, 0, 2, 0, 5, 0], #3
# [ 0, 0, 4, 0, 1, 0, 3, 0, 0], #4
# [ 0, 2, 0, 9, 0, 5, 0, 0, 0], #5
# #
# [ 0, 0, 1, 0, 3, 0, 5, 9, 0], #6
# [ 0, 0, 0, 4, 0, 0, 6, 0, 3], #7
# [ 0, 0, 0, 0, 0, 0, 0, 2, 0], #8
## 0, 1, 2, 3,|4, 5, 6,|7, 8
# ]
#a = [
# [0,0,2,4,5,0,7,0,0]
# ,[0,4,0,0,0,8,0,3,0]
# ,[8,0,1,0,0,3,5,0,6]
# ,[0,5,3,0,0,0,0,0,4]
# ,[7,0,0,0,0,0,0,0,2]
# ,[2,0,0,0,0,0,6,7,0]
# ,[3,0,6,5,0,0,1,0,7]
# ,[0,2,0,1,0,0,0,5,0]
# ,[0,0,7,0,2,9,4,0,0]
# ]
#a = [
# [0, 0, 0, 0, 0, 0, 0, 0, 0], #0
# [0, 0, 0, 0, 0, 0, 0, 0, 0], #1
# [0, 0, 0, 0, 0, 0, 0, 0, 0], #2
# #
# [0, 0, 0, 0, 0, 0, 0, 0, 0], #3
# [0, 0, 0, 0, 0, 0, 0, 0, 0], #4
# [0, 0, 0, 0, 0, 0, 0, 0, 0], #5
# #
# [0, 0, 0, 0, 0, 0, 0, 0, 0], #6
# [0, 0, 0, 0, 0, 0, 0, 0, 0], #7
# [0, 0, 0, 0, 0, 0, 0, 0, 0], #8
## 0, 1, 2, 3,|4, 5, 6,|7, 8
# ]
#===============================================================================
# 得到坐标点和值,相当于稀疏矩阵:(X,Y):value
#===============================================================================
exists_d = dict(((h_idx, y_idx), v)
for h_idx, y in enumerate(a)
for y_idx , v in enumerate(y) if v)
h_exist = defaultdict(dict)
v_exist = defaultdict(dict)
#===============================================================================
# 二维数组
#===============================================================================
for k, v in exists_d.iteritems():
h_exist[k[0]][k[1]] = v
v_exist[k[1]][k[0]] = v
#===============================================================================
# 生成所有的组合
#===============================================================================
permutations = tuple(itertools.permutations(range(1, 10), 9))
h_d = {}
now = time.time()
#===============================================================================
# 取得行号与该行符合条件的组合
#===============================================================================
for hk, hv in h_exist.iteritems():
#===========================================================================
# 过滤横向,x轴与同行已知的点的值重复的组合
#===========================================================================
q = filter(lambda x:all((x[k] == v
for k, v in hv.iteritems())), permutations)
#===========================================================================
# 过滤纵向,Y轴与同列已知的点的值重复的组合
#===========================================================================
q = filter(lambda x:all((x[vk] != v
for vk , vv in v_exist.iteritems()
for k, v in vv.iteritems()
if k != hk)), q)
h_d[hk] = q
#===============================================================================
# 不全某行没有任何提示
#===============================================================================
for line_idx in range(0, 9):
if line_idx not in h_d:
h_d[line_idx] = permutations
print time.time() - now
def filter_by_column(y, resource_dict):
'''@summary: 纵向过滤重复的值
@param y: 待检测的一行排列
@param resource_dict: 列序号及组合在对应列号的值列表
'''
if not resource_dict:
return 1
return all((y[k] not in v for k, v in resource_dict.iteritems()))
sudokus = []
def check_3_lines(f, s, t):
'''@summary: 检测3行的每三列是不是符合条件
@param f: first line
'''
if len(set((f[0], f[1], f[2], s[0], s[1], s[2], t[0], t[1], t[2]))) != 9:
return 1
if len(set((f[3], f[4], f[5], s[3], s[4], s[5], t[3], t[4], t[5]))) != 9:
return 1
if len(set((f[6], f[7], f[8], s[6], s[7], s[8], t[6], t[7], t[8]))) != 9:
return 1
return 0
def check_2_lines(f, s):
'''@summary: 检测两行数据的每三列是不是有重复值,提前淘汰有重复值的组合
@param f: first line
'''
if len(set((f[0], f[1], f[2], s[0], s[1], s[2]))) != 6:
return 1
if len(set((f[3], f[4], f[5], s[3], s[4], s[5]))) != 6:
return 1
if len(set((f[6], f[7], f[8], s[6], s[7], s[8]))) != 6:
return 1
return 0
def solve_sudoku(h_d, h_idx=None, reserves=None
, solves=None, resource_dict=None):
'''
@param reserves: 已经验证过符合条件的排列
@param solves: 最终的解决方案集合
@param resource_dict: dict key in range(1,10),values 是每行同一列的数字的列表
'''
if solves is None:
solves = []
if h_idx is None :
h_idx = 0
for l0 in h_d[h_idx]:
if reserves == None:
_reserves = [l0, ]
solve_sudoku(h_d, h_idx + 1, _reserves, solves)
else:
if not filter_by_column(l0, resource_dict):
continue
if h_idx in (1 , 4, 7):
if check_2_lines(reserves[h_idx - 1], l0):
continue
elif h_idx in (2, 5, 8) :
if check_3_lines(reserves[h_idx - 2], reserves[h_idx - 1], l0):
continue
_reserves = list(reserves)
_reserves.append(l0)
if h_idx < 8:
solve_sudoku(h_d, h_idx + 1, _reserves, solves
, dict((idx, set([i[idx] for i in _reserves]))
for idx in range(0, 9)))
if h_idx == 8:
solves.append(_reserves)
print u"calc No. {num} result".format(num=len(solves))
print u"*" * 50
for i in solves[-1]:
print i
else:
if h_idx == 0:
return solves
if __name__ == '__main__':
#(8, 7, 9, 1, 2, 3, 4, 6, 5)
#(5, 4, 3, 7, 9, 6, 2, 1, 8)
#(1, 6, 2, 5, 8, 4, 7, 3, 9)
#(7, 1, 8, 3, 4, 2, 9, 5, 6)
#(9, 5, 4, 6, 1, 8, 3, 7, 2)
#(3, 2, 6, 9, 7, 5, 8, 4, 1)
#(6, 8, 1, 2, 3, 7, 5, 9, 4)
#(2, 9, 7, 4, 5, 1, 6, 8, 3)
#(4, 3, 5, 8, 6, 9, 1, 2, 7)
now = time.time()
x = solve_sudoku(h_d)
print time.time() - now
# profile.run(u"solve_sudoku(h_d)", filename=r"d:\test.txt")
# import pstats
# p = pstats.Stats(r"d:\test.txt")
# p.sort_stats("time").print_stats()
python 数独_python 实现 数独 解法 (穷举法)相关推荐
- python穷举法_python 穷举指定长度的密码例子
本程序可根据给定的字符字典,穷举指定长度的所有字符串: def get_pwd(str, num): if(num == 1): for x in str: yield x else: for x i ...
- Python:三种方法计算最大公约数和最小公倍数(欧几里德法、穷举法、stein算法)
Python:三种方法计算最大公约数和最小公倍数 1.穷举法 2.欧几里德法 3.Stein算法 题目:求取任意两个非负数(至多一个数为0)的最大公约数和最小公倍数: 参考资料:Python解决求最大 ...
- python算24点穷举法_24点游戏7节课–第1节-游戏介绍与基本算法 | 学步园
这仅仅是一个控制台(DOS窗口下)的小游戏--有人欢喜有人烦了.欢喜的是因为可以专心于游戏逻辑自身过程,就算你只学过C++简单的屏幕输入输出(cin.cout ),乃至换用java,C#也可以写这个小 ...
- python计算圆周率(蒙特卡洛法/模拟法、统计法/穷举法、BBP公式)
def calculatePI1(): #模拟统计法:蒙特卡罗方法计算圆周率import random as r #导入random模块命名为rimport math as m #导入math模块命名 ...
- python求两个数的最大公约数穷举法_C++求最大公约数四种方法解析
C++求最大公约数的四种方法思路,供大家参考,具体内容如下 将最近学的求最大公约数的四种方法总结如下: 第一种:穷举法之一 解释:拿其中一个数出来,用一个临时变量(tem)保存,每次都把那两个数除以这 ...
- python穷举法列举_穷举法应用举例.doc
无 止 境 穷举法应用举例 在数学问题中, 有一些需要计算总数或种类的趣题, 因其数量关系比较隐蔽, 很难找到"正统"的方式解答,让人感到无从下手.对此,我们可以先初步估计 其数目 ...
- 穷举法python例子_(Python)简单线性模型与穷举优化,穷举法
一个简单的线性模型,使用穷举法计算所有最小二乘误差,并生成分析图. import numpy as np import matplotlib.pyplot as plt # 简单线性模型-穷举法优化 ...
- Python解决鸡兔同笼问题(while穷举法)
解决鸡兔同笼问题常见有两种方法 第一种是列函数计算法,第二种是while进行穷举 这里展示一下个人感觉比较不常用的穷举法 所谓穷举法,就是利用while循环让计算机在获得你输入的数值之后进行不断的试错 ...
- python三种方法开根号(穷举法、二分法、牛顿拉夫逊法)
文章目录 方法一:穷举法 方法二:二分法 方法三:牛顿-拉夫逊算法 总结 方法一:穷举法 positive_num = int(input("输入一个正数:")) #无穷逼近法 a ...
- 算法设计之—直接 遍历/穷举法、贪心算法、动态规划、回溯法、EM方法
算法是对完成特定问题的程序执行序列描述,表象为从问题初始状态到问题结束状态的所有路径之中寻找可行路径,若无先验经验,根据执行方式不同可以划分为无规则和有规则(启发式)方法. 无规则方法为穷举,改进方法 ...
最新文章
- Windows Phone开发(32):路径之PathGeometry 转:http://blog.csdn.net/tcjiaan/article/details/7469512...
- 【STC15库函数上手笔记】5、定时器
- 【转】ABP源码分析十三:缓存Cache实现
- 常规sql读取CLOB
- 2020年生活服务业新业态和新职业从业报告
- PHP笔记-Smarty模板引擎的使用
- java基础—找出两个字符串中最大的子串
- 安卓rom制作教程_【ROM消息】Simplicity官改:MIUI11 9.12.14全机型更新
- Arcgis制作行政区划矢量文件(shp格式)
- 利用DroidCam将手机摄像头打造成电脑摄像头
- wps怎么把两张图片组合_如何对word/wps中的多个图片进行组合。 专家详解
- 使用STK卫星轨道无法显示——解决方法
- php 逻辑思维题,倘若3分钟内,你能答对这道智力题,说明你的逻辑思维能力很强...
- 【软件测试】使用RFT工具录制脚本要点
- Fabric.js添加辅助线的方法
- word文档在保存后消失,如何恢复?
- CICD -- pipeline 流水线
- C# 实现安卓和iOS app 读写数据库,实现手机本地存储
- c语言用递归求奇数和,奇数正整数和的递归算法
- 网易我的世界服务器如何装组件,网易我的世界组件包怎么使用-网易我的世界组件包如何使用...