软件工程基础个人项目--生成数独终局并且能求解数独问题的控制台程序-2019-12-24至2019-12-31

GitHub项目地址:

GitHub - KennyH33/sudoku


任务:

实现一个能够生成数独终局并且能求解数独问题的控制台程序


PSP表格

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

2019年12月28日更新

需求分析:

实现一个命令行程序,程序能:
1.生成不重复的数独终局至文件
2.读取文件内的数独问题,求解并将结果输出至文件

生成终局

1.在命令行中使用-c参数加数字N(1<=N<=1000000)控制生成数独终局的数量,例如下述命令将生成20个数独终局至文件中:

sudoku.exe -c 20

2.将生成的数独终局用一个文本文件(假设名字叫做sudoku.txt)的形式保存起来,每次生成的txt文件需要覆盖上次生成的txt文件,文件内的格式如下,数与数之间由空格分开,终局与终局之间空一行,行末无空格。

9 5 8 3 6 7 1 2 4
2 3 7 4 5 1 9 6 8
1 4 6 9 2 8 3 5 7
6 1 2 8 7 4 5 9 3
5 7 3 6 1 9 4 8 2
4 8 9 2 3 5 6 7 1
7 2 4 5 9 3 8 1 6
8 9 1 7 4 6 2 3 5
3 6 5 1 8 2 7 4 9
···

3.程序在处理命令行参数时,不仅能处理正确的参数,还能够处理各种异常的情况,如:

sudoku.exe -c abc

4.在生成数独矩阵时,左上角的第一个数为:(学号后两位相加)%9+1.例如学生A学号后两位是01,则该数字是(0+1)%9+1=2,那么生成的数独棋盘应如下(x表示满足数独规则的任意数字):

2 x x x x x x x x
x x x x x x x x x
x x x x x x x x x
x x x x x x x x x
x x x x x x x x x
x x x x x x x x x
x x x x x x x x x
x x x x x x x x x

求解数独

1.在命令行中使用-s参数加文件名的形式求解数独,并将结果输出至文件,如:

sudoku.exe -s absolute_path_of_puzzlefile

2.格式如下,其中0代表空格,题目与题目之间空一行,行来无空格,最后一个数独题目后无空行:

9 5 0 3 6 7 0 2 0
2 0 7 0 5 0 9 6 0
0 0 6 9 2 8 3 5 0
6 1 0 8 7 4 5 9 3
5 0 3 0 1 9 0 8 2
4 8 0 0 3 5 6 7 1
7 2 4 5 9 0 8 1 0
8 0 0 7 4 6 2 3 0
3 6 5 1 8 2 7 4 9
···

3.sudoku.txt的格式如下(与生成终局的要求相同):

9 5 8 3 6 7 1 2 4
2 3 7 4 5 1 9 6 8
1 4 6 9 2 8 3 5 7
6 1 2 8 7 4 5 9 3
5 7 3 6 1 9 4 8 2
4 8 9 2 3 5 6 7 1
7 2 4 5 9 3 8 1 6
8 9 1 7 4 6 2 3 5
3 6 5 1 8 2 7 4 9
···

4.数独题目个数N(1<=N<=1000000),以保证文件中数独格式正确。


功能建模:

这里使用DFD进行面向数据流建模

"数独处理程序"的顶层图

"数独处理程序"的1层图

2019年12月31日更新

解题思路:

生成终局

这里参考了xxrxxr的cnblogs软工博客,使用模板法生成终局,首先生成一个模板终局,因为学号后两位是01,所以第一个数字2不能动((0+1)%9+1=2),基本数独可以依靠第一行向左分别移动0,3,6,1,4,7,2,5,8位形成九行,也就是一个数独,而第一行的个数是除去2的8个数字的全排列,即8!=40320种,基本数独也是40320种,远远不足以达到题目中1000000的要求,这时候需要用到行列交换的方法,但是在这道题中,只需要交换行即可,因为第一个数字不能动,所以前三个3×3矩阵中只能第二行与第三行交换,也就是整个9×9的矩阵中的第二行与第三行互相交换,但是后面的数字没有要求,所以第4,5,6行可以进行互相交换,第7,8,9行可以进行互相交换,这样一种基本数独可以衍生出2!×3!×3!=72个数独,总个数也就是72*40320=2903040个,几乎是题目要求的3倍多,这样就达到了题目目的。

求解数独

看到题目要求之后我的想法是使用回溯法,即深度优先搜索,从第一个0开始,填入1-9中可以满足需求的数字,然后继续,如果遇到9个数字都无法填入的情况则返回上一个空位用别的数字代替,以此类推,最后能得到一个解好的数独。


剩余博客的更新将在该账号主页下用新的文章发表

2020年1月4日更新
2020年1月8日更新
2020年1月15日的博客更新
2020年1月19日的博客更新

你可能感兴趣的:(软件工程基础个人项目--生成数独终局并且能求解数独问题的控制台程序-2019-12-24至2019-12-31)