数独大作业

软件工程基础——数独终局生成与求解(一)

  • 一、代码链接
  • 二、项目介绍
  • 三、项目设计与实现过程
    • 1、PSP表格预估需要花费的时间
    • 2、解题思路描述

一、代码链接

Github地址:https://github.com/tennisintheworld/sudoku

二、项目介绍

实现一个能够生成数独终局并且能求解数独问题的控制台程序。
要求使用参数sudoku -c加数字n(1<=n<=1e6),生成n个数独终局,并输出到文件sudoku.txt中;使用参数-s加文件名,求解文件中的数独,并将结果输出到文件sudoku.txt中。

三、项目设计与实现过程

1、PSP表格预估需要花费的时间

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

2、解题思路描述

(1)生成终局的思路:

看到题目的时候第一眼注意到了最多要生成1e6个终局,而且还有效率时间上的限制要求,那么暴力方法是绝对不行的,时间肯定会超出很多。然后看到了终局左上角第一个是一个固定的数字,即(学号后两位相加)%9+1,那么剩下的8个数字最多可以排列组合生成8!=40320种组合,然后按一定的方法平移生成其他8行,这样可以减少时间。

可行性分析:

  • 首先,按照排列组合生成的行,行内肯定没有重复的数字;
  • 其次,移动第一行的数字,只要每次移动的方向一样,一次一次的移动,生成2-9行,就能保证生成的终局列内也没有重复。
  • 每三列(即123,456,789三组)平移的时候都移动间隔为3的倍数,可以保证每三行形成的九宫格里面没有重复的数字。

然而数量上远远不够,在受到旁人指点之后,知道了可以分成三三三的小组,在组内部再次排列组合。前三个由于第一个不能动,只有两种平移方式(即036,063的平移规则);第二组的三个有六种(即147,174,417,471,714,741的平移规则),第三组的也是六种(即258,285,528,582,825,852的平移规则)。总共能有2 * 6 * 6 * 40320种,远大于1e6了。

然后是具体的搜索方法,我采用了回溯的方法,配合生成的排列数和移动的规则,应该能够很快的生成终局。

(2)求解数独的思路

由于求解数独没有时间要求,而且我也没有很多求解数独的心得体会,所以决定直接使用回溯法,尽量剪枝和优化搜索。首先搜索整个数独问题的区域,找到没有数字的格子。然后尝试性的放入数字,继续向后面填入数字。那么会出现两种情况:

  • 第一种是能够填满,这就说明了这是可行解。
  • 第二种是走到某个格子的时候,发现1-9都不能填入其中,这时候要往前回溯,因为肯定是前面填错了,反复尝试,直到填满,找到可行解。

由于数独肯定有一个解,所以这种解法肯定能够找到可行解,不用担心没有解而一直回溯。

你可能感兴趣的:(数独大作业)