软件工程个人项目—数独

£可爱£侵袭症+ 提交于 2020-01-19 00:17:28

Sudoku项目流程(心路历程)

项目地址 github仓库

主要内容

  • PSP 2.1 表格
  • 项目的准备过程
  • 项目实现过程
  • 项目的分析改进过程

PSP 2.1表格

PSP 2.1 Personal Software Process Stages 预计耗时(分钟) 实际耗时(分钟)
Planning 计划 50 60
Estimate 估计这个任务需要多久 300 360
Development 开发 240 270
Analysis 需求分析 25 25
Design Spec 生成设计文档 60 60
Design Review 设计复审 10 10
Coding Standard 代码规范 5 5
Design 具体设计 20 20
Coding 具体编码 240 240
Code Review 代码复审 5 5
Test 测试 30 30
Reporting 报告 60 60
Test Report 测试报告
Size Measurement 计算工作量
Postmortem & Process Improvement Plan 事后总结,提出过程改进意见

项目准备过程

  • 碎碎念

    在刚知道个人作业是写一个数独小项目时,我的内心是崩溃的。因为我从来就没有玩过数独,看见老师发的pdf里生成终局的示例那一长串的数字,我的内心感到十分抗拒。。。

    所以这个作业一直拖着没有做直到今天。。。(12.27)

    我的动手能力较差,而且也没有相关的经验,所以在预估时间时,心里很没底,基本每一项都是往大了填


  • 在大概了解整个项目后,我认为自己需要学习的技能有以下几点:

    • git命令的使用 (用于项目的版本控制)
    • markdown语法的使用(用于写这篇博客)
    • 回溯法等算法的复习(用于生成数独和解决数独)
    • 代码质量分析工具的使用
    • 性能分析工具的使用

    P.S. ORZ 我是真的好菜啊,都大三了这些东西居然还不会用


  • 需求分析

    实现一个命令行程序,程序能:

    1. 生成不重复的数独终局至文件
    2. 读取文件内的数独问题,求解并将结果输出到文件

    生成终局

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

      sudoku.exe -c 20

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

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

      shudoku.exe -c abc

    4. 在生成数独矩阵时,左上角第一个数为:(学号后两位相加)%9+1。例如学号后俩位是63,则该数字为(6+3)%9+1 = 1,那么生成的数独棋盘的第一个数字应为1。

    求解数独

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

      sudoku.exe -s absolute_path_puzzlefile

      程序将从路径中读取数独题目并将数独题目的一个可行解输出至与sudoku.exe同目录的sudoku.txt中,要求与生成终局相同。

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

    3. sudoku.txt的格式与生成终局的要求相同。

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

  • 什么是数独

    数独(shù dú)是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复

项目实现过程

  • 生成数独终局

    数独是一个9*9的矩阵,矩阵中每一行、每一列、每一宫的数字都只能出现一次。

    • 搜索 + 剪枝 (没有采用)

      第一行按照要求以学号后2位确定第一个数字,剩下8个数字随意写出一个排列,第2行到第9行通过搜索产生。即第2行到第9行的每一个空格都从19逐个放入看是否合法(同一行同一列同一宫没有相同数字出现过),若合法则尝试放入,然后递归地搜索下一个位置上的数字,若19中没有数字合法,则退回上一层递归尝试下一个数字,直到填满9*9矩阵中的所有位置。这样我们可以通过变换第一行的排列顺序得到 8!= 40320 个数独,然后再通过交换2、3行,46行,79行再乘以3!*3!,可以生成的终局数量大于需求要求的1000000。但是考虑到通过这种算法生成终局在搜索过程中每个位置都要进行判断,耗费时间,经过网上资料查询发现了下一种方法。

    • 通过数独模板生成数独终局

      数独模板:

      a b c d e f g h i
      d e f g h i a b c
      g h i a b c d e f
      b a d c f d h i g
      c f d h i g b a d
      h i g b a d c f d
      e c a f d b i g h
      f d b i g h e c a
      i g h e c a f d b

      我们可以发现这个数独模板是从第二行开始,每行分别是第一行右移3、6、1、4、7、2、5、8列的结果。我们还可以发现,对于任何一个数独终局的13行,我们任意交换这三行的顺序,得到的仍然是一个合法的终局,46行和79行同理,列也同理。我们还可以发现,对于任何一个数独终局的13行,我们任意交换这三行的顺序,得到的仍然是一个合法的终局,46行和79行同理,列也同理。由于需求中要求生成的终局数量N(0<=N<=1e6),而且数独的第一个数字是确定的,所以我们通过变换第一行的数字可以得到8!= 40320个数独,再通过交换2、3行,456行、789行可以得到823!*3!个数独,大于1e6满足需求,不需要再进行列变换。

    • 类图

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!