0. Description
item uploaded to GitHub for safekeeping and live updating GitHub links
The blog will be updated in real time based on the development process. I. Pre-development PSP table Estimation
PSP2.1 |
Personal software Process Stages |
Estimated time-consuming (minutes) |
Planning |
Plan |
|
· Estimate |
. Estimate how long this task will take |
1200 |
Development |
Development |
|
· Analysis |
. Demand analysis (including learning new technologies) |
180 |
· Design Spec |
. Creating a design Document |
60 |
· Design Review |
. Design Review (and colleagues review design documents) |
20 |
· Coding Standard |
. Code specification (to develop appropriate specifications for current development) |
20 |
· Design |
. Specific design |
120 |
· Coding |
. Specific code |
400 |
· Code Review |
. Code review |
30 |
· Test |
. Test (self-test, modify code, commit changes) |
200 |
Reporting |
Report |
|
· Test Report |
. Test report |
30 |
· Size Measurement |
. Computational effort |
30 |
· Postmortem & Process Improvement Plan |
. Summarize afterwards and propose process improvement plan |
60 |
|
Total |
1150 |
second, the project thinking
The project consists of generating a specified number of Sudoku ends and solving a given Sudoku mess, which in fact can be seen as a problem, resulting in a final equivalent to solving all the blanks of the endgame. Therefore, a function can be used to complete two functions.
Analogy to the N queen problem, the first thought of solving Sudoku is the backtracking method. The fill of a single number is recursive, and if the number of this fill does not meet the criteria, it is traced back to the previous number. In addition, prior to learning the algorithm, the contact dancing links algorithm, the classic application is to solve Sudoku, but only a rough understanding, no practice.
Considering the complexity of the two, we decided to try backtracking first. To avoid generating a regular final, I will initialize the first row of numbers in advance, and randomly generate the order of the attempted numbers, thus avoiding the same final generation. Third, the design realization process
Because the project requires two functions, it is divided into two modules. Read the parameters in the main function and judge, read into the main function by reading into the completion. After obtaining the parameters, select the corresponding function to enter. The two main functions are to solve the function and generate the final function, both of which call the fill function. To ensure the randomness of the generation, there are two functions that are used to randomly initialize the first row and randomly generate an attempt to numeric order.
Unit tests include read-in function tests, solving function tests, and generating function tests. Read-in function tests will read the valid numbers and the illegal characters, and test whether they can give a reasonable response. The solve function test will use the Sudoku puzzle of a small use case to test whether it can give positive solutions. The build function tests whether it can generate a specified number of final results, and verifies the randomness of the finality.
Unit test run and test results:
Four, performance improvement
The first version of the full feature, which takes approximately 10s of time to generate a 1e5 use case, is time consuming. The following figure shows the CPU usage and function invocation of version 1 on 1e5 use cases, and the visible fill function is the most expensive function.
As a result of brute force search, the worst case scenario is to try nine numbers for a grid, up to nearly 80 levels for each number, and so the backtracking operation reaches 9^80 times, resulting in a high degree of complexity. After a search, it is found that the resulting one can be converted to a different number of final results using a method of exchanging rows, columns, interchange numbers, and matrix transpose, without affecting its correctness. Because of the special requirements on the upper left corner number, the method of exchanging rows and columns is chosen to produce partial finality, thus reducing the overall complexity.
By exchanging the method, the set will generate a final extension into 20 final, so that the problem size is reduced by nearly 20 times times, the generation of 1e5 of the use case only need about 4s, greatly shorten the time. The following diagram shows the modified program performance.
In this way, we continue to improve, directly generate 20 Sudoku as a seed matrix, and then randomly expand the 20 matrices into 1000 matrices. This avoids the problem of generating a final dense similarity when a single matrix is expanded.
The final program can be achieved to generate 1e6 final of approximately 40s.
Only 10s after the output is changed to Putchar. Five, code description
The most critical part of the fill function, using backtracking to populate the numbers sequentially from top left to right. Called in both the resulting final and Solver Sudoku.
int Fill_sudoku (int s,int x,int y) { //fill function
int init = board[s][x][y]; Record initial value
int next_x = x + (y + 1)/9, next_y = (y + 1)% 9; Next grid coordinates
if (x >= 9) //complete
return 1;
if (Board[s][x][y]) { //The current lattice is populated
if (Fill_sudoku (s,next_x, next_y))
return 1;
}
else{ //Current space for
(int i = 0; i < 9; i++) {
int try_num = try_list[i]; Current attempt number
if (Judge (s,x, Y, Try_num)) { //Judging legal
board[s][x][y] = try_num;
if (Fill_sudoku (s,next_x, next_y))
return 1;}}
}
Board[s][x][y] = init; Revert back to
return 0;
}
To generate the seed matrix section, first fill 1-9 randomly into the first row, then randomize the order of numbers when backtracking, and then call the fill function to solve the fill.
memset (Board, 0, sizeof (Board)); Empty the palace for
(int i = 0; i < i++) { //Round 20 seed matrix
Random_init (board[i][0]); Randomly initialize the first line of numbers for
(int j = 0; J < 9; + j)
if (board[i][0][j] = = 5) { //# Two (%9+1=5)
swap (board[i][ 0][0], board[i][0][j]);
break;
}
Random_init (try_list); Random initialization of digital attempt sequence
Fill_sudoku (i, 1, 0); Start padding
}
For the extended portion of the final, randomly select one of the 20 final, and then generate a new final by exchanging rows and columns.
int sand = rand ()%;
Swap_col (sand, 1, 2), Swap_row (sand, 1, 2);
Swap_col (Sand, 3, 5), Swap_row (Sand, 3, 5);
Swap_col (sand, 6, 8), Swap_row (sand, 6, 8);
Vi. actual situation of PSP tables
PSP2.1 |
Personal software Process Stages |
Estimated time-consuming (minutes) |
actual time elapsed (minutes) |
Planning |
Plan |
|
|
· Estimate |
. Estimate how long this task will take |
1200 |
—— |
Development |
Development |
|
|
· Analysis |
. Demand analysis (including learning new technologies) |
180 |
150 |
· Design Spec |
. Creating a design Document |
60 |
30 |
· Design Review |
. Design Review (and colleagues review design documents) |
20 |
60 |
· Coding Standard |
. Code specification (to develop appropriate specifications for current development) |
20 |
20 |
· Design |
. Specific design |
120 |
180 |
· Coding |
. Specific code |
400 |
420 |
· Code Review |
. Code review |
30 |
120 |
· Test |
. Test (self-test, modify code, commit changes) |
200 |
120 |
Reporting |
Report |
|
|
· Test Report |
. Test report |
30 |
30 |
· Size Measurement |
. Computational effort |
30 |
30 |
· Postmortem & Process Improvement Plan |
. Summarize afterwards and propose process improvement plan |
60 |
120 |
|
Total |
1150 |
1280 |