利用程序随机构造N个已解答的数独棋盘
一、PSP(个人软件过程)
PSP1.1 | Personal Software Process Stages | 预估耗时(minutes) | 实际耗时(minutes) |
---|---|---|---|
Planning |
计划 | 30 | 45 |
· Analysis | · 需求分析 (包括学习新技术) | 120 | 140 |
· Code Review | · 代码复审 | 20 | 25 |
· Coding | · 具体编码 | 210 | 230 |
· Coding Standard | · 代码规范 | 20 | 10 |
· Design | · 具体设计 | 30 | 30 |
· Design Review | · 设计复审 | 5 | 5 |
· Design Spec | · 生成设计文档 | 10 | 15 |
· Estimate | · 估计任务所需时间 | 10 | 5 |
· Postmortem & Process Improvement Plan | · 总结 | 30 | 20 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Test | · 测试(自我测试,Debug,提交修改) | 110 | 125 |
· Test Report | · 测试报告 | 20 | 30 |
合计 | 625 | 690 |
二、项目要求
1.目标:随机生成N个已解答完毕的的数独棋盘矩阵,在控制台中键入"xxxx.exe -c N"格式的命令后将矩阵输出到当前路径下的‘sudotiku.txt’文件中。
2.限制条件:N值为0~1000000,矩阵不重复。
三、算法思路
1.利用回溯法来决定矩阵中每个数字的填法(编写sudomatrixgenerator函数):首先确定数独矩阵中第一行的数字(利用random头文件包含下的shuffle函数进行1~9的随机排列),从第二行第一个数字开始,尝试依次填入数字,填入后依据数独规则进行可行性判断。如果可以填入该数字,则对下一格进行相同的判断。如果某一格对于任何数字的填入都违反了数独规则,则进行回溯,重新填上一格的数字。
当获得一个可行结果时,算法终止。
2.在主函数中根据键入的参数值多次调用sudomatrixgenerator函数,将所生成的数独矩阵写入文本文件中,并设置异常捕获。
四、具体源码
#include <iostream> #include <chrono>//std下的一个子命名空间,为持续时间类服务chrono::system_clock #include <random>//shuffle随机排列函数 default_random_engine #include <algorithm>//使用for_each循环 #include <functional>//定义了多个类模板 #include<fstream> using namespace std;void sudomatrixgenerator( int num) //数独矩阵生成函数 {int field[9][9] = { 0 }; //随机生成一行1~9auto init = [](int* list) //使用auto进行变量类型的自动匹配 {for_each(list, list + 9, [=](int &i) //用来遍历list进行操作 =for(int i=0;i<9;i++) {i = &i - list + 1;});unsigned seed = chrono::system_clock::now().time_since_epoch().count();//调用当前系统时间作为随机种子seed的初始值shuffle(list, list + 9, default_random_engine(seed));//生成随机序列,将list至list+9区间内的数值随机排列 };init(field[0]); //初始化第一行元素int trylist[9];init(trylist); //用于确定数字的尝试顺序auto judge = [&field](int i, int j, int num) -> bool //判断填入的数字是否合法 { for (int k(0); k < j; k++) //判断同一行中是否有重复元素if (field[i][k] == num)return false;for (int k(0); k < i; k++) //判断同一列中是否有重复元素相同if (field[k][j] == num)return false;int count = j % 3 + i % 3 * 3; //判断整个3*3区域中是否有重复元素while (count--)if (!(field[i - i % 3 + count / 3][j - j % 3 + count % 3] - num))return false;return true; };function<bool(int, int, int*)>//类模板 fill = [&trylist, &fill, &field, judge](int y, int x, int* numloc) -> bool //用简单回溯方法进行数字的填入 {if (y > 8)return true;if (judge(y, x, *numloc)) {field[y][x] = *numloc;if (fill(y + (x + 1) / 9, (x + 1) % 9, trylist))return true;}field[y][x] = 0;if (numloc - trylist >= 8)return false;if (fill(y, x, numloc + 1))return true;};fill(1, 0, trylist);//确定某位置要填入的数字//根据参数输出相应的数独矩阵for (int k = 0; k <= num;k++) {for (int i(0); i < 9; i++) { for (int j : field[i])cout << j << " ";cout << endl;}cout << endl;//每个矩阵相隔一行 }return; }//总程序入口处 int main(int argc, char *argv[]) {int N;//要输出的矩阵个数bool check(char *c)//用来判断在命令行中输入的第三个参数是否为数字 {int len = strlen(c);//获取字符串长度for (int i = 0; i < len; i++) {if (!isdigit(c[i]))return false;}return true;}if (!(argc == 3 && !strcmp(argv[1], "-c") && check(argv[2]))) {//判断输入的命令格式是否符合规范cout << "参数输入错误!" << endl;return 1;}N = atoi(argv[2]);//将命令行中获取到的第三个字符转换为数字ofstream out;//定义文件流对象try{out.open("sudotiku.txt", ios::trunc); //文件不存在则创建,文件存在则清空其中的数据再输入数据 }catch (const std::exception&)//异常捕获 {cout << "打开文件:sudoku.txt 失败!!";}sudomatrixgenerator(N);//生成N个数独棋盘矩阵out.close();//关闭sudotiku.txt文件return 0; }
五、测试运行
cmd窗口下键入命令:
输出至sudotiku.txt中:
测试结果基本无误,未产生重复矩阵。
六、性能分析
n=20的cpu时间:12.541秒
cpu占用:
各函数占用:
七、心得体会
1.本次学习时长大致为11hours,在此次数独棋盘程序编写的过程当中,回溯法的运用无疑是一大关键,其实可以把回溯法看成是递归调用的一种特殊形式。但对于CS的学生来说,从来没使用过回溯法来解决问题(比如迷宫问题和八皇后问题)的情况是很少见的,不过往往是“对症下药”,针对特定的问题进行解答。这些天看了看《算法设计与分析》回溯法相关内容,觉得对回溯法抽象的很好。如果说算法是解决问题步骤的抽象,那么这个回溯法的框架就是对大量回溯法算法的抽象,再结合以前数据结构这门课程里面的深度优先搜索策略来看,运用回溯法解数独问题会在逻辑上更容易接受,同时自己也对C++11的特性有了更加深入的了解,复习了对象与类的基本方法,学会了如何利用git提交源码至Coding服务器上。
2.所遇到的问题:如何快速的确定数独矩阵中第一行的数字 相应解决方法是查阅C++相关书籍(如C++ primer)以及阅读某CSDN博主的博客后尝试运用shuffle方法(附该博主博客地址https://blog.csdn.net/elloop/article/details/50397618)
另一问题是C++函数库的使用问题,在程序调试阶段报错为“无法打开某源文件xxxx”,后证实(以VS2017举例)可在编译器中项目属性一栏的平台工具集中设置其版本为VS2010或以下,再次build即可解决。
转载于:https://www.cnblogs.com/ecutwzl1996/p/9744995.html
利用程序随机构造N个已解答的数独棋盘相关推荐
- fpga加载程序慢_FPGA的DONE信号在加载程序后无法拉高 (已解答)
在使用ISE进行FPGA的bit文件下载时,经常会遇到下载失败的问题,提示:"DONE did not go high". 在Xilinx官网上有对此问题的答复如下: 下面提供以下 ...
- 【小程序】C语言实现简易钢琴-利用sin函数构造不同频率波形模拟各琴键发音
根据钢琴音调频率对照表,使用sin函数构造对应频率正弦波数据模拟各琴键声音,实现简易钢琴效果,结果写入wav文件中. 目录 程序效果 实现过程 样例代码 测试用例 参考资料 程序效果 截图1:键位图 ...
- PHP程序随机输出一些字符串内容,已集成方法可直接使用
在博客中会用到一些随机显示的内容(字符串),将每1条内容按行切分,再随机显示一组,代码如下: /*** PHP程序随机输出一些内容,名言什么的* @return $poems* @Time 2018. ...
- 数组随机抽取 java_Java利用数组随机抽取幸运观众如何实现
这篇文章主要介绍了Java利用数组随机抽取幸运观众如何实现,需要的朋友可以参考下 编写程序,事先将所有观众姓名输入数组,然后获得数组元素的总数量,最后在数组元素中随机抽取元素的下标,根据抽取的下标获得 ...
- 利用GBDT模型构造新特征具体方法
利用GBDT模型构造新特征具体方法 数据挖掘入门与实战 公众号: datadw 实际问题中,可直接用于机器学**模型的特征往往并不多.能否从"混乱"的原始log中挖掘到有用的 ...
- ML之shap:基于FIFA 2018 Statistics(2018年俄罗斯世界杯足球赛)球队比赛之星分类预测数据集利用RF随机森林+计算SHAP值单样本力图/依赖关系贡献图可视化实现可解释性之攻略
ML之shap:基于FIFA 2018 Statistics(2018年俄罗斯世界杯足球赛)球队比赛之星分类预测数据集利用RF随机森林+计算SHAP值单样本力图/依赖关系贡献图可视化实现可解释性之详细 ...
- 【编译原理】【实验】利用子集法构造DFA
利用子集法构造DFA 一.实验目的 二.实验要求.内容 三.实验设备 四.实验原理(或程序框图)及步骤 五.程序源代码 六.实验数据.结果分析 七.存在的问题与体会 附录 一.实验目的 掌握将非确定有 ...
- 如何编写自己的缓冲区溢出利用程序(下)(转)
如何编写自己的缓冲区溢出利用程序(下)(转) (续) by 黑猫(virtualcat@hotmai.com) 值得注意的是: 如果象上面所说的, 我们输入的字串长度为二十个'A'--刚好复盖完0xb ...
- 极域电子教室-利用程序-轻松入侵全班同学电脑
前段时间参加了培训 ,上课的时候用的是"极域电子教室 V6 2007 豪华版": 这个系统分教师端和学生端的,我们是学生,装的是学生端: 出于好奇,我开了两个虚拟机,一个安装教师端 ...
最新文章
- mysql子查询缺点_[慢查优化]慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时
- java中que_java中==和eques比较
- 代码大全(第二版)笔记——高质量的子程序
- php ueditor怎么用,ueditor PHP版本使用方法
- VI 修改^M为unix换行符
- 【版本控制】如何从github 上获取源码
- 显著性目标检测matlab代码_YOLO v3 目标检测终篇(附完整 GitHub 代码)
- Linphone-Android源码学习(一)
- 线性反馈移位寄存器 LFSR
- bochs镜像java模拟器_bochs镜像下载
- KeyError: 'labels [189] not contained in axis' Python DataFrame 合并后使用loc进行索引的时候出错问题分析以及解决方案
- vue实战 —— 图书商城移动端项目
- 【c++】《搜索习题集》题解,更新至DFS之搜索顺序
- WSO2 XMl转JSON
- android广播教程,Android学习笔记(广播机制)
- C. Neko does Maths
- 微信小程序表格实现隔行换色
- 5G和车联网的本质联系
- 深入理解Java虚拟机(周志明第三版)- 第十三章:线程安全与锁优化
- Python中 list[:]与 list 的区别
热门文章
- 腾讯WiFi码推广,扫码连WiFi小程序代理入驻后如何推广使用教程!
- C# 实现类似SMSS的执行脚本的功能
- 铨顺宏RFID:射频技术应用在服装资产管理上有什么作用
- CSS 开源资源大全收集
- Linux--系统网络测试和测试工具
- 面试答案-简单回答k8s容器启动的过程
- MySql 查重、去重的实现
- 【cs224n学习作业】Assignment 1 - Exploring Word Vectors【附代码】
- Python自动生成ffmpeg转码HEVC (X265,H265) 命令
- Field ‘browser‘ doesn‘t contain a valid alias configuration