博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
高级软件工程第二次作业——个人项目实战:数独
阅读量:4600 次
发布时间:2019-06-09

本文共 3120 字,大约阅读时间需要 10 分钟。

第二次作业——个人项目实战

1).项目地址

github地址:
使用语言:c++
运行环境:WIN10
开发平台:Visual Studio Professional 2017 15.3.5
2).解题思路
其实在我看到第二次作业已经发布的时候,我的内心是极其崩溃的,因为我前一天才赶着在假期开始之前把第一次作业做完,第二次作业就已经悄无声息的来到了我的面前。在我第一次看到这个题时,这个题目给我的感觉是“应该”不难。我第一时间想到的是这个题目需要三个判断函数,用来满足填入数字的规则,即同一行无重复,同一列无重复,同一九宫格无重复。但我那时一直有一个很大的疑惑,即这三个函数如何实现一次性判断无重复。后来发现我对这个题目的理解还停留在一种“静态”的思维,即一种填完之后再判断正确性的思维当中。之后我开始通过搜索引擎查找了关于“数独”的很多题目。其中有很多方法有参考价值,如最基本的单个填写再判断。生成随机行之后做置换等等。其中有一种方法比较有趣,即利用一个填写好的数独来进行变换,得到其他数独。受上述方法启发,我决定使用先填写一个子块再填写其余块的方法来实现数独的生成。
3).设计实现
采用一个静态二维数组来实现这个9*9的宫格,其中由题目所设,宫格中的数字为1-9,且行不重复,列不重复,九宫格不重复。也就是说,每行每列每个九宫格都是1-9的组合。数独每填完一个,就循环输出一个数独组合。然后初始化棋盘。上述都是基本的步骤,最重要的步骤是填入方法。在初始化过的棋盘中,生成不重复的随机数字来填写第一个九宫格。然后循环填写后续九宫格。在填写不进去时,尝试其他随机组合,但有可能现在的组合已经是无解的,所以设置一个尝试次数用来防止程序陷入死循环中。这里将其设置为100,即尝试填写100次失败之后就更换第一个九宫格中的随机组合。
4).代码说明
主函数部分
···

int C = atoi(argv[argc - 1]);answerout.open("sudoku.txt");if (C >0){    bool back;    int TryTimes = 0;    srand((unsigned)time(NULL));     int i = 0;    while(i < C)//数独输出循环    {        back = false;        if (TryTimes > 0&&TryTimes<100)//尝试次数较少        {            InitRest(answer);        }        else if (TryTimes==0)//开始状态        {            InitAll(answer);            SubBuild(answer, 0);        }        else if(TryTimes>=100)//尝试次数大于100次后变更第一个九宫格组合        {            InitAll(answer);            SubBuild(answer, 0);        }        for (int j = 1; j < 9; j++)//尝试构建后续八个九宫格        {            bool success = SubBuild(answer, j);            if (!success)            {                 back = true;                break;            }        }        if (back)//构建失败,尝试次数加一,根据尝试次数选择策略        {            TryTimes++;        }        else//构建完成,输出数独        {            for (int x = 0; x < 9; x++)            {                for (int y = 0; y < 9; y++)                {                    answerout << answer[x][y] << ' ';                }                answerout << endl;                if (x == 8)                    answerout<< endl;            }            TryTimes = 0;             i++;        }    }    answerout.close();}//错误输出else cout << "Please input a natural number" << endl;return 0;

···

5).测试运行

1249115-20171007151907036-749852281.png

1249115-20171007152141177-521619042.png

6).性能分析

使用VS自带的性能探查器中的CPU采样分析方法,输入为5000.得到如图报表
1249115-20171007152858568-877967554.png
使用VS自带性能探查器中的监测分析方法,输入为1000,得到如下报表
1249115-20171007153811490-1349053011.png
两种分析方法使用后,可知程序在构建九宫格时所消耗的时间和资源最多。所以可以尝试减少构建九宫格所需的时间和资源,最直接的方式便是减少尝试次数,由于题目的要求只是生成指定数量的数独,对于一初始九宫格和其后续可能存在无解情况,我们可以控制其尝试次数以求获得更多的组合来进行有意义的尝试,而减少对一无解问题的尝试。还有一点便是优化“放弃”该组合并初始化的后续九宫格的退回范围,即尝试次数过多后只初始化最后两个九宫格,如不行,再初始化三个,依次类推。由于时间有限,只对减少尝试次数这一优化方法进行了探索。发现在减少尝试次数的同时,程序有可能放弃本来有效的解,尤其是在尝试次数过低时,也就是说。这个尝试次数应该存在一个近似最优的值。
下图为函数耗时和函数调用次数
1249115-20171008103024153-1863277503.png
1249115-20171008103110403-1796907697.png

7).PSP

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

转载于:https://www.cnblogs.com/xiezhe1204/p/7634938.html

你可能感兴趣的文章
linux常用端口
查看>>
异常处理
查看>>
/proc/uptime详解
查看>>
如何建立合适的索引?
查看>>
acwing 651. 逛画展
查看>>
(待完成)qbxt2019.05 总结12 - 趣味题目 鹰蛋
查看>>
[2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
查看>>
关于WPF程序只运行一个实例的方法
查看>>
图论:点分治
查看>>
mysql
查看>>
C/C++ 知识点---sizeof使用规则及陷阱分析(网摘)
查看>>
java小程序 示例
查看>>
前端开发在线小工具
查看>>
有关cookies使用方法
查看>>
Hadoop 使用Combiner提高Map/Reduce程序效率
查看>>
前言 转录组
查看>>
局域网内访问机器时出现“未授予在次计算机上的请求登陆类型”
查看>>
Bogart BogartAutoCode.vb
查看>>
GIT
查看>>
关于OPENSSL的EVP函数的使用
查看>>