python实现解数独程序代码

 更新时间:2017年04月12日 08:45:11   作者:未曾见海  
最近在带孩子学习数独,职业使然,就上网搜了下相关程序的解法,这里分享给大家,希望对大家学习python有所帮助

偶然发现linux系统附带的一个数独游戏,打开玩了几把。无奈是个数独菜鸟,以前没玩过,根本就走不出几步就一团浆糊了。

于是就打算借助计算机的强大运算力来暴力解数独,还是很有乐趣的。

下面就记录一下我写解数独程序的一些思路和心得。

一.数独游戏的基本解决方法

编程笼统的来说,就是个方法论。不论什么程序,都必须将问题的解决过程分解成计算机可以实现的若干个简单方法。俗话说,大道至简。对于只能明白0和1的计算机来说,就更需要细分步骤,一步一步的解决问题了。

首先来思考一下解数独的基本概念。

数独横九竖九共八十一个格子,同时又分为9个九宫格。规则很简单——需要每一个格中的数字,都保证与其所在横排和竖排以及九宫格内无相同数字。

所以我们的大概思路就是,从第一个空格开始试着填数,从 1 开始填,如果 1 不满足横排竖排九宫格无重复的话,就再填入 2 ,以此类推,直到填入一个暂时满足规则的数,中断此格,移动到下一个空格重复这个过程。

如果到达某个空格发现已经无数可选了,说明前面某一格填错了,那就返回上一格,从上一格的中断处继续往 9 尝试,直到这样回朔到填错的那一格。

这样的话,我们就可以整理出重要的步骤了:

•寻找到下一个空格
•轮流填入格中数字 1 到 9
•递归判断填入数是否符合规则

二.程序

首先测试数独使用的是芬兰数学家因卡拉花费3个月时间设计出的世界上迄今难度最大的数独。如下

将空格用 0 表示,同时将数独表示成嵌套的列表,这样每格的行数和列数就正好是列表中每个对应数的索引。

程序如下:

 #coding=utf-8
 import datetime
 class solution(object):
   def __init__(self,board):
     self.b = board
     self.t = 0
 
   def check(self,x,y,value):#检查每行每列及每宫是否有相同项
     for row_item in self.b[x]:
       if row_item == value:
         return False
     for row_all in self.b:
       if row_all[y] == value:
         return False
     row,col=x/3*3,y/3*3
     row3col3=self.b[row][col:col+3]+self.b[row+1][col:col+3]+self.b[row+2][col:col+3]
     for row3col3_item in row3col3:
       if row3col3_item == value:
         return False
     return True
 
   def get_next(self,x,y):#得到下一个未填项
     for next_soulu in range(y+1,9):
       if self.b[x][next_soulu] == 0:
         return x,next_soulu
     for row_n in range(x+1,9):
       for col_n in range(0,9):
         if self.b[row_n][col_n] == 0:
           return row_n,col_n
     return -1,-1 #若无下一个未填项,返回-1
 
   def try_it(self,x,y):#主循环
     if self.b[x][y] == 0:
       for i in range(1,10):#从1到9尝试
         self.t+=1
         if self.check(x,y,i):#符合 行列宫均无条件 的
           self.b[x][y]=i #将符合条件的填入0格
           next_x,next_y=self.get_next(x,y)#得到下一个0格
           if next_x == -1: #如果无下一个0格
             return True #返回True
           else:    #如果有下一个0格,递归判断下一个0格直到填满数独
             end=self.try_it(next_x,next_y)
             if not end:  #在递归过程中存在不符合条件的,即 使try_it函数返回None的项
               self.b[x][y] = 0  #回朔到上一层继续
             else:
               return True
 
   def start(self):
     begin = datetime.datetime.now()
     if self.b[0][0] == 0:
       self.try_it(0,0)
     else:
       x,y=self.get_next(0,0)
       self.try_it(x,y)
     for i in self.b:
       print i
     end = datetime.datetime.now()
     print '\ncost time:', end - begin
     print 'times:',self.t
     return
 
 
 s=solution([[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,8,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]])
 73 s.start()

值得注意的是使用的递归判断能够很巧妙的在走错分支时回朔到上一层。具体实现是通过 for 循环来从 1 到 9 不断填入数字同时达到记录中断点的作用。通过下一层的返回值来确定是否回朔。

程序输出如下:

[8, 1, 2, 7, 5, 3, 6, 4, 9]
[9, 4, 3, 6, 8, 2, 1, 7, 5]
[6, 7, 5, 4, 9, 1, 2, 8, 3]
[1, 5, 4, 2, 3, 7, 8, 9, 6]
[3, 6, 9, 8, 4, 5, 7, 2, 1]
[2, 8, 7, 1, 6, 9, 5, 3, 4]
[5, 2, 1, 9, 7, 4, 3, 6, 8]
[4, 3, 8, 5, 2, 6, 9, 1, 7]
[7, 9, 6, 3, 1, 8, 4, 5, 2]

cost time: 0:00:00.060687
times: 45360

可以看到程序虽然运算次数比较多,但是速度还是很快的。

相关文章

  • Python实现比较扑克牌大小程序代码示例

    Python实现比较扑克牌大小程序代码示例

    这篇文章主要介绍了Python实现比较扑克牌大小程序代码示例,具有一定借鉴价值,需要的朋友可以了解下。
    2017-12-12
  • 关于torch.optim的灵活使用详解(包括重写SGD,加上L1正则)

    关于torch.optim的灵活使用详解(包括重写SGD,加上L1正则)

    今天小编就为大家分享一篇关于torch.optim的灵活使用详解(包括重写SGD,加上L1正则),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • 5分钟教会你用Docker部署一个Python应用

    5分钟教会你用Docker部署一个Python应用

    Docker是一个开源项目,为开发人员和系统管理员提供了一个开放平台,可以将应用程序构建、打包为一个轻量级容器,并在任何地方运行,下面这篇文章主要给大家介绍了关于如何通过5分钟教会你用Docker部署一个Python应用,需要的朋友可以参考下
    2022-06-06
  • Python NumPy教程之二元计算详解

    Python NumPy教程之二元计算详解

    二元运算符作用于位,进行逐位运算。二元运算只是组合两个值以创建新值的规则。本文将为大家详细讲讲Python NumPy中的二元计算,需要的可以了解一下
    2022-08-08
  • 在Python中利用Bokeh创建动态数据可视化

    在Python中利用Bokeh创建动态数据可视化

    在本文中,我们探讨了如何利用 Bokeh 库在 Python 中创建动态数据可视化,我们介绍了 Bokeh 的基本概念和优势,以及如何安装 Bokeh 库,对在Python中利用Bokeh创建动态数据可视化相关知识感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • Python实现各种排序算法的代码示例总结

    Python实现各种排序算法的代码示例总结

    这篇文章主要介绍了Python实现各种排序算法的代码示例总结,其实Python是非常好的算法入门学习时的配套高级语言,需要的朋友可以参考下
    2015-12-12
  • Python pickle 二进制序列化和反序列化及数据持久化详解

    Python pickle 二进制序列化和反序列化及数据持久化详解

    这篇文章主要介绍了Python pickle 二进制序列化和反序列化 - 数据持久化,模块 pickle 实现了对一个 Python 对象结构的二进制序列化和反序列化,本文介绍了Pickle的基本用法,需要的朋友可以参考下
    2024-01-01
  • Python+Turtle制作七夕爱心光波表白的示例代码

    Python+Turtle制作七夕爱心光波表白的示例代码

    七夕要来啦,小编在闲暇之余创作了一个基于Python+Turtle的爱心光波表白,文中有详细的代码示例,对我们七夕表白有很大的帮助,感兴趣的小伙伴们快来来看看吧
    2023-08-08
  • 开源软件包和环境管理系统Anaconda的安装使用

    开源软件包和环境管理系统Anaconda的安装使用

    Anaconda是一个用于科学计算的Python发行版,支持 Linux, Mac, Windows系统,提供了包管理与环境管理的功能,可以很方便地解决多版本python并存、切换以及各种第三方包安装问题。
    2017-09-09
  • python控制台显示时钟的示例

    python控制台显示时钟的示例

    这篇文章主要介绍了python控制台显示时钟的示例,需要的朋友可以参考下
    2014-02-02

最新评论