软件工程个人项目— 数独

1120173032 王晗

Github:https://github.com/lion-han/sudoku

目录

软件工程个人项目— 数独

PSP2.1 表格

个人日报:

程序功能简介:

结题思路:

生成终局

生成题目

求解数独

设计实现过程(另一篇博客)

代码组织

代码说明

单元测试(另一篇博客)

性能分析(另一篇博客)


PSP2.1 表格

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

个人日报:

日期 工作情况 耗时
12.23 分析并选题 60min
12.24 创建博客、github仓库、需求分析、解题思路 90min
12.25 解题思路 50min
12.26 学习DLX算法、生成数独终局,github托管调试 190min
12.27 完成数独题目生成部分,github托管成功 170min
12.28 完成解数独部分(暴力解),加入命令行分析与报错,进行代码结构化调整 250min
12.29 vs项目出错,修改bug,重建项目,push 180min
1.14 发现没有进行行的交换,修改代码,实现生产1200000个不同的数独 150min
1.15 学习单元测试工具之间的区别,学习安装使用gtest进行单元测试 200min
1.16 优化数独生成时间,尝试不同文件读写方式 240min
1.17 学习vs性能分析工具,进行string字符串处理的优化,文件读写的优化 300min
1.18 继续学习单元测试,完成单元测试,进行覆盖率,进行代码分析,修改错误 360min
1.19 补充单元测试,组织博客内容 300min

程序功能简介:

实现一个命令行程序,具有以下功能:

  1. 生成不重复的N个数独终局至文件(1<=N<=1000000)

  2. 读取文件内的数独问题,求解并将结果输出到文件

具体需求详见软件工程基础-个人项目文档

结题思路:

生成终局

最开始的想法是一位一位的产生数独的每位数字,但是总也想不出高效的解决方法。于是上网查了些资料,并通过自己画图研究数独时发现,想要生成数目庞大的数独终局,不能通过随机的分配或者一位一位产生,必须通过一定规律的变化得到。

我发现通过确定第一行的数,后面7行通过对第一行不同的移位可产生一个数独终局。由于每个3*3的方块内不能有重复的数,所以1、2、3行,4、5、6行,7、8、9行内位移必须大于等于3,不然会出现重复。

通过变化第一行的数顺序,其余7行移位规律不变(),可产生8!=40320个终局(第一位固定,后面7行移位规律相同)

之后可以通过2、3行,4、5、6行,7、8、9行内交换任意两行可得到不同的矩阵,共2*6*6=72种变化

通过上述变化可产生 8! *(2*6*6)=2903040>1e6 可满足条件,并且分析后不会产生相同的数独。

但是如何进行第一行的全排列是一个问题,首先我想到的是,通过遍历来解决,但是9个数字需要9^9 的时间消耗来解决,显然不可行,然后我想到类似于桶排序的方法确定每位是否被用过,但是并不能提升效率。然后上网搜索,发现一种康托展开的方法,它是一个全排列到一个自然数的双射,可以把一个自然数转换成一个对应的全排列,也可以把一个全排列转换成一个对应的自然数,使用逆康托展开可以在O(N*N)的时间复杂度下形成一个全排列。效率有了很大的提升。实现个小模块之后,通过与ACM室友的交流,我了解到c++里有一个产生全排列的函数 next_permutation 可以产生全排列。于是我去网上搜索它的实现原理,next_permutation 通过分析全排列的规律来交换数字反向操作实现下一个全排列,时间复杂度可达O(N),已经非常好了。

全排列问题解决了,如何进行第一行的移位呢,首先顺序移位是有点慢的O(N),使用链表可达到O(1),但是链表比较麻烦,最终想出了将第一行数字再连接一个第一行数字,通过每次取不同位置的9个数即可,可达到O(1)。

然后便是交换数独的行,形成新的数独,由于要求第一行首为与学号有关的特定数,所以第一行不动,交换其他行。首先我想到的是实现一个函数用来交换特定行的内容,但是这不仅要求交换两行,而且要求交换3行,且交换的规律是特定的很难通过递归循环来实现。于是我想到根据上面形成的初始数独,对他的行的排列写一个30*9的数组,规定行的顺序,然后按照顺序进行数独的生成。

生成题目

由于上一步已经产生了许多数独终局,所以数独问题的产生就可以依靠产生的数独终局文件了。读取数独终局文件,通过输入参数n,可以生成n个数独题目。题目的生成通过随机给数独的位置赋值0来解决。也可以加入一个空白比例参数实现题目的难度级别。再写入文件。

求解数独

开始时感觉数独求解应该很费时间,所以先去网上搜索了一下数独的求解问题。发现了一个DLX算法用来解决精准覆盖的问题,刚好可以用在解数独上,它通过一种双向十字链表的数据结构加上搜索来解决问题。但是把它用来解数独实践起来还是有点难度。毕竟是一个软件工程项目,不仅仅是程序设计问题,所以我就先使用简单的DFS(深度优先搜索)进行数独的求解。在实现后发现挖空率在60%都可以非常快的求解出来,所以就先使用DFS来解数独了。分析挖空率为50%的数独,发现实际上求解还是挺简单的,每个空可填的数字都非常有限。所以决定使用DFS来实现数独求解。

其他博客:

设计实现过程(另一篇博客)

单元测试(另一篇博客)

性能分析(另一篇博客)

软件工程个人项目— 数独相关推荐

  1. BIT软件工程个人项目——数独sudoku

    BIT软件工程个人项目--数独sudoku 目录: (点击可页内跳转) 1. 项目地址 2. PSP表格 3. 解题思路描述 --3.1初期思考 --3.2数独终局生成 --3.3求解数独 4. 设计 ...

  2. 软件工程基础-个人项目-数独游戏

    软件工程基础-个人项目-数独游戏 ----------------------------------------------------------------------------------- ...

  3. 软件工程基础个人项目——数独(5)

    软件工程基础个人项目--数独 点击这里可看github上的具体代码 本次个人项目关于数独的生成与求解 PSP表格 PSP2.1 Personal Software Process Stages 预估耗 ...

  4. 软件工程基础——个人项目——数独(1)

    软件工程基础--个人项目--数独(1) 一.实现目标 1.生成数独终局 命令行输入如下: sudoku.exe -c 20 sudoku.exe为最终实现程序,-c确定活动为生成数独终局,20为生成结 ...

  5. 软件工程基础-个人项目-数独

    个人项目–数独 目录) 个人项目--数独 1 项目地址 2 PSP表格 3 思路描述 3.1 数独终局生成 3.1.1. 暴力法 3.1.2. 全排列及行变换 3.2 功能实现思路 3.2.1. 数独 ...

  6. 软件工程个人项目——买书的最低价格

    软件工程个人项目--买书的最低价格 题目要求: 书店针对<哈利波特>系列书籍进行促销活动,一共5卷,用编号0.1.2.3.4表示,单独一卷售价8元, 具体折扣如下所示: 本数        ...

  7. 大三软件工程小项目-小技术集合总结

    大三软件工程小项目-小技术集 此篇文章是给出了此小项目用到的技术的总结: 方便自己有忘记的知识点后方便查阅. 也方便有需要的博友看. 下面是各个计算的链接 大家点击了进能进去 大三软件工程小项目-小技 ...

  8. 现代软件工程团队项目贝塔阶段_大规模测试结果_2018.02.08

    现代软件工程团队项目贝塔阶段_大规模测试结果_2018.02.08 经过课程全班同学测试后,将收集到的所有BUG和建议汇总如下 BUG按照状态.严重程度.优先级进行了基本的分类 目前打算的BUG修改顺 ...

  9. JavaWeb项目-快递代领-需求分析(二)-软件工程-小组项目

    快递带领-需求分析 1.项目简介 1.1项目背景 快递又称速递或快运,是指物流企业(含货运代理) 通过自身的独立网络或以联营合作(即联网)的方式,将用户委托的文件或包裹,快捷而安全地从发件人送达收件人 ...

  10. 软件工程小组项目——单词计数

    软件工程小组项目--单词计数 项目地址 PSP表格 解题思路 实现过程 1.字符数 2.单词数 3.行数 4.各段行数统计 5.对子目录文件进行操作 6.图形界面 性能优化 实验总结 项目地址 Git ...

最新文章

  1. Kaggle经典数据分析项目:泰坦尼克号生存预测!
  2. 婚姻是唯一没有领导者的联盟
  3. Java学习 第三章 数组(二)多维数组
  4. 前端学习(1933)vue之电商管理系统电商系统之优化树形控件
  5. emacs中安装markdown-mode
  6. 作者:李雪梅(1984-),女,烟台中科网络技术研究所研发工程师。
  7. Dart 3-Day
  8. win7·64bit+VS2013+opencv的简单配置
  9. Linux内核漏洞精准检测如何做?SCA工具不能只在软件层面
  10. C/C++ 最易受攻击、70% 漏洞无效,揭秘全球开源组件安全现状
  11. 用友U8审批流相关开发
  12. Firefox中强制复制粘贴的插件
  13. stm32+ESP8266实现最简单的手机控制LED灯
  14. [全网首发]坚果Pro3 root教程 Magisk
  15. C语言伽罗华域乘法,伽罗瓦域上的乘法
  16. java 某年某月的天数_1160-C语言实验——某年某月的天数-JAVA
  17. 做了3年单片机工程师,如果工资还是3-5千,那你就看过来
  18. MyBatis自带的缓存配置(Cache)
  19. c语言求数字b在a中出现次数,编写一个函数void fun(char *tt,int pp[]),统计在tt字符中a到z26各字母各自出现的次数,并依次放在pp所指的数组中。...
  20. 回顾Win10自带表情包快捷键

热门文章

  1. mysql根据日周月分组计算
  2. SQL语句中case、when、then的使用
  3. 快速搭建基于《搜狗微信》的公众号爬虫---搜狗微信公众号爬虫教程
  4. 台式计算机麦说不了话,耳机有声音麦克风没声音怎么办?解决电脑耳机有声音麦不能说话...
  5. 第一次训练----跳房子
  6. 数字逻辑——七段数码管
  7. 修改win10搜索框(Cortana)调用默认浏览器(edge)和搜索引擎
  8. VSCODE一个阴坑
  9. java生成eml_用Java创建一个.eml(email)文件
  10. 【python】给excel加密