我正在尝试为数独(9x9网格)实现回溯求解器,非常基本。
伪代码逻辑:
backtrack():
choose random **empty** cell
generate random value (1 ....9)
check if it fits(or is good for - row,column,region):
if yes - occupy this cell , recurse
if no - put the cell value to zero
约束:在相同的行,相同的列和相同的区域中没有相似的数字。(区域-3x3块)
我看不到我的逻辑缺陷,但它存在!
这是c ++代码:
bool basic_sudoku_with_random_picking( int table[][9] ){
if(find_empty_cell(table) == false ) return true ;// no empty cells? success!
int row = -1 ;
int column = -1 ;
int x, y ;
x = 1 + rand() % 9 ;//generate random x
y = 1 + rand() % 9 ;//gen random y
if( table[x][y] == 0){// see if the cell is zero (zero - free)
row = x ;
column = y ;
int try_num = 1 + rand()% 9 ;// found empty cell - try random number on it!
if( is_good(table, row,column, try_num) ){
table[row][column] = try_num ;
return ( basic_sudoku_with_random_picking(table) ) ;
}
else{ table[row][column] = 0 ;
return false ;
}
}
else return basic_sudoku_with_random_picking(table) ;
}
//check row
bool is_row_good(int table[][9], int row , int num){
for(int column = 0 ; column < 9 ; column++ ){
if (table[row][column] == num ){
return false ;}
}
return true ;
}
//check column
bool is_column_good(int table[][9], int column , int num){
for(int row = 0 ; row < 9 ; row++ ){
if (table[row][column] == num ){
return false ;}
}
return true ;
}
//check block- region
bool check_region(int table[][9], int x1, int y1, int x2, int y2, int check){
for(int i = x1; i <= x2 ;i++){
for(int j = y1 ; j <=y2 ;j++){
if(table[i][j] == check){
return false ;}
}
cout <<endl ;
}
return true ;
}
bool is_block_good(int table[][9], int i, int j , int num){
if(i >= 0 && i <=2){
if( j <= 2 ) check_region(table,0,0,2,2, num) ;// 1 region
if(j >= 3 && j<=5)check_region(table,0,3,2,5, num) ;//2 region
if(j >=6 && j<=8)check_region(table,0,6,2,8, num) ;//3 region
}
if(i >=3 && i <=5){
if(j <=2 ) check_region(table,3,0,5,2, num) ;//4 block
if(j >= 3 && j<=5)check_region(table,3,3,5,5, num) ;//5 block
if(j >= 6 && j<=8)check_region(table,3,6,5,8, num) ;//6 block
}
if( i >=6 && i <=8){
if(j<= 2) check_region(table,6,0,8,2, num) ;//7 block
if(j >= 3 && j<=5)check_region(table,6,3,8,5, num) ;// 8 block
if(j >= 6 && j<=8)check_region(table,6,6,8,8, num) ;//9 block
}
}
//check all 3 constraints
bool is_good(int table[][9], int i, int j, int try_num){
//cout << "CHECKING CELL in general" <<endl ;
return (is_row_good (table, i, try_num) &&
is_column_good(table, j, try_num) &&
is_block_good (table, i , j,try_num) ) ;
}
bool find_empty_cell(int table[][9]){
for(int i = 0 ; i < 9 ; i++){
for(int j = 0 ; j < 9 ; j++){
if( table[i][j] == EMPTY_CELL){// found empty cell
return true ;
}
}
}
return false ;
}
最佳答案
您遇到的实际问题是什么?
这是我发现的一个问题:
x = 1 + rand() % 9 ;//generate random x
y = 1 + rand() % 9 ;//gen random y
if( table[x][y] == 0){
...
因为
table
是作为table[/*something*/][9]
存储的2d数组,所以您可能会尝试访问超出数组范围的内存,因为y可以取值1-9(包括1和9)。请记住,C ++使用0索引的内存,因此您只应访问0-8(含0)的索引。编辑:
只是为了发布后代修复程序。
x = rand() % 9 ;//generate random x
y = rand() % 9 ;//gen random y
关于c++ - 数独解决每次回溯选择随机单元格和随机值的回溯逻辑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21412129/