0. GitHub项目地址
本项目对应的GitHub代码仓库点此进入
1. PSP 表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
- Estimate | - 估计这个任务需要多少时间 | 20 | 25 |
Development | 开发 | ||
- Analysis | - 需求分析(包括学习新技术) | 150 | 70 |
- Design Spec | - 生成设计文档 | 90 | 120 |
- Design Review | - 设计复审(和同事审核设计文档) | - | - |
- Coding Standard | - 代码规范(为目前的开发制定合适的规范) | - | - |
- Design | - 具体设计 | 90 | 60 |
- Coding | - 具体编码 | 300 | 720 |
- Code Review | - 代码复审 | 90 | 60 |
- Test | - 测试(自我测试,修改代码,提交修改) | 240 | 180 |
Reporting | 报告 | ||
- Test Report | - 测试报告 | 60 | 50 |
- Size Measurement | - 计算工作量 | 30 | 20 |
- Postmortem & Process Improvement Plan | - 是否总结,并提出过程改进计划 | 30 | 30 |
Total | 总计 | 1100 | 1335 |
2. 解题思路
本题要求实现实现一个能生成数独终局并独立求解数独问题的程序。
主要需求如下:
- 能够生成数独终局
- 能够独立求解数独
2.1 生成数独终局
根据项目要求,需要生成 1 0 6 10^6 106个不重复数独。由于需求并未要求数独的难度,故可以考虑使用数独的特性来寻找生成简单而不同的数独的通法。
2.1.1 生成数独的通法
不妨设数独的第一行为: a , b , c , d , e , f , g , h , i a,b,c,d,e,f,g,h,i a,b,c,d,e,f,g,h,i,
令 A = { x ∣ 1 ≤ x ≤ 9 a n d x ∈ N } A= \left\{x|1 \leq x \leq 9 \; and \; x \in N \right\} A={
x∣1≤x≤9andx∈N}
B = { x ∣ 0 ≤ x ≤ 8 a n d x ∈ N } B= \left\{x|0 \leq x \leq 8 \; and \; x \in N \right\} B={
x∣0≤x≤8andx∈N}
我们可以按照如下方式构建一个合法的数独:
令数独的k行为第一行向右移动 f ( k ) f(k) f(k)列。故: f ( 1 ) = 0 f(1) = 0 f(1)=0
由于数独每一列必须取到 a a a到 i i i中的所有值,故 f ( k ) f(k) f(k)是从 A A A到 B B B的双射函数。
同时,由于每个 3 × 3 3\times3 3×3的 子网格也包含 a a a到 i i i中的所有值,即在 3 × 3 3\times3 3×3的小方格中不能出现重复数字,要求:
f ( 2 ) ≥ f ( 1 ) + 3 f(2) \geq f(1) + 3 f(2)≥f(1)+3, f ( 3 ) ≥ f ( 2 ) + 3 f(3) \geq f(2) + 3 f(3)≥f(2)+3, f ( 3 ) ≤ f ( 1 ) + 6 f(3) \leq f(1) + 6 f(3)≤f(1)+6
f ( 5 ) ≥ f ( 4 ) + 3 f(5) \geq f(4) + 3 f(5)≥f(4)+3, f ( 6 ) ≥ f ( 5 ) + 3 f(6) \geq f(5) + 3 f(6)≥f(5)+3, f ( 6 ) ≤ f ( 4