天天看点

软件工程个人项目-数独

项目地址:

https://github.com/Bit-Bertram-Guan/

项目要求

1.求解数独,读取文件内的数独问题(规模为1~1000000),求解并将结果输出到文件。

2.实现生成不重复的数独终局(规模为1~1000000):

并要求输入能够处理各种异常状况;

   数独左上角第一个元素为(学号后两位相加)%9+1;
           

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划
·Estimate ·估计这个任务需要多少时间 30
Development 开发
·Analysis ·需求分析(包括学习新技术) 100
·Design Spec ·生成设计文档 90
·Design Review ·设计复审(和同事审核设计文档) 10
·Coding Standard ·代码规范(为目前的开发制定合适的规范) 30
·Design ·具体设计 120
·Coding ·具体编码 1500
·Code Reivew ·代码复审 120
·Test ·测试(自我测试,修改代码,提交修改) 150
Reporting 报告 240
·Test Report ·测试报告 150
·Size Measurement ·计算工作量 30
·Postmortrm & Process Improvement Plan ·事后总结,并提出过程改进计划 60
合计 2390

解题思路描述

要解决这个问题,首先要知道数独游戏的规则

数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。———引用自《数独_百度百科》

最初拿到这个题目的时候,自认为是大作业中比较简单的,但是实际做的时候,心里一阵翻腾。老师让用gtihub托管代码,这一部分我也不太熟悉,所以额外还花费点功夫。难点在于如何设计完成题目中很多细碎的功能。

最开始的想法是深度遍历,暴力搜索,但是考虑到对于性能的要求,这显然是不可取的。

因此,我转变了方向,决定从网络上寻求一个更好的方法来解决数独问题。我查阅了许多资料,翻看了很多的博客,了解了许多之前写过类似题目的前辈们的想法,发现生成数独终局的方法大概有如下几种:

   1、回溯法。随机生成数字填入当前网格中,检测是否符合要求,如果符合则继续生成数字填到下一个网格,否则回溯到上一步,不断随机生成数字直到所有网格被填满。

   2、模板法。事先准备好一个符合要求的数独终局模板,模板中的元素为字母a~i,然后随机生成一串包含1-9的数字序列,将字母一一对应,替换为数字,获得数独终局。

   3、数列法。生成一个数列,然后将此数列分别向右移动0、3、6、1、4、7、2、5、8位得到终局第一到第九行。可以将第1~3行对应的移动位数改变一下顺序,如改为0、6、3,就可以得到一个新终局。此外,4到6,7到9行也可以更改。于是一个数列可以生成6^3=216个终局,数字1到9可以生成9!= 362880个数列。

一个数独终局的生成可以用第一行的平移来形成。平移的时候只要满足一定规律,就可以使新生成的数独终局满足数独三原则:横行无重复,纵行无重复,3×3方格内无重复。

规格是这样:

①下面的几行由第一行平移得到,先给定第一行的一个排列,只要第一行的排列是1到9这9个不重复的数,就可以满足每一横行内无重复。

②满足上一条前提下,只要下面几行在平移的时候每一行平移错开的位数不同,就可以保证9个列都是不包含重复数字。

③为了让3×3方格也满足规则,平移时,每三行一组,组内每行间平移错开的位数相差3。比如:用{0,3,6}表示前三行的情况,意思是:给定一个排列第一行可以看做是向前平移了0个长度。第二行相当于第一行向前平移3个长度。第三行相当于第一行向前平移6个长度。用这种方法中间三行是{1,4,7},后三行是{2,5,8}。

对数独的求解,使用回溯法搜索所有可能结果即可。

设计实现过程

生成数独终局

软件工程个人项目-数独

求解数独

软件工程个人项目-数独