回溯到sudoku求解每次选择随机单元和随机值的逻辑
Backtracking logic for sudoku solving choosing random cell and random value each time
我正在尝试为sudoku(9x9 grid)实现回溯求解器,非常基础。
伪代码逻辑:
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(包括)。请记住,C 使用0个索引内存,因此您只能访问索引0-8包含索引。
编辑:只是为了张贴后期的修复。
x = rand() % 9 ;//generate random x
y = rand() % 9 ;//gen random y
相关文章:
- 什么时候调用组成单元对象的析构函数
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么 Serial.println(<char[]>);返回随机字符?
- 字符串-C++后显示的随机字符
- 不同翻译单元中不可重载的非内联函数定义
- 循环中的随机函数
- 在c++构造函数中使用随机字符串生成器
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- VC++本机单元测试,找不到调试符号
- 使用std::mt19937从字符串中返回一个随机单词
- 将QIcon添加到QTableView单元格
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- 如何在C++中高效地构造随机骰子
- 在类中使用随机生成器时出现性能问题
- 在将数字随机生成为数组期间从内存输出随机数的数组
- 用于交叉编译和CMake的预处理器宏的单元测试
- 当用户在qtablewidget中输入单元格时,如何获得信号?C++
- 回溯到sudoku求解每次选择随机单元和随机值的逻辑
- 非单元迭代器跨接非随机访问迭代器