数独 约束求解 C++ and Python
程序员文章站
2022-06-26 10:31:04
利用每一个空格的域空间进行约束求解,注释应该够了,直接贴代码
C++:
#include
#include
#include
#include
#inclu...
利用每一个空格的域空间进行约束求解,注释应该够了,直接贴代码
C++:
#include #include #include #include #include using namespace std; vector CurDom[81]; int map[9][9]; vector< vector > answer; int num_of_blank; int able_num[9]; int Assigned[81]; int counts = 0 ; void init_CurDom(int map[9][9], int index )//index表示0~81某一位置索引,将该索引位置的行,列,方块进行检查,把可走的数字的域放入CurDom[index]的容器中 { for ( int k = 0 ; k < 9 ; k ++ ) able_num[k] = k + 1;//先初始为1~9,将行,列,方块中出现的数字的索引置为0,不为零的即为可走域 int i = index/9; int j = index%9; for ( int row = 0 ; row < 9 ; row ++ ) if ( map[row][j] != 0 ) able_num[ map[row][j] - 1 ] = 0; for ( int col = 0 ; col < 9 ; col ++ ) if ( map[i][col] != 0 ) able_num[ map[i][col] - 1 ] = 0; for ( int r = i/3*3 ; r < i/3*3 + 3 ; r ++ ) for ( int c = j/3*3 ; c < j/3*3 + 3 ; c ++ ) if ( map[r][c] != 0 ) able_num[ map[r][c] - 1 ] = 0; for ( int k = 0 ; k < 9 ; k ++ ) if( able_num[k] != 0 ) CurDom[index].push_back( able_num[k] ); } void init(int map[9][9],int & num)//初始化操作,num表示空格数目 { for (int i = 0 ; i < 9 ; i ++ ) for ( int j = 0 ; j < 9 ; j ++ ) { int index = i*9+j; if( map[i][j] == 0 ) { num ++; init_CurDom( map, index ); } else Assigned[i*9+j]=1;//已经有值的位置置为1 } } int PickAnUnassignedVariable()//找出可走的index,即为访问过的具有最少域空间的index值 { int min_value = 10; int min_index = 82; for ( int i = 0 ; i < 81 ; i ++ ) { if(Assigned[i] == 0 && CurDom[i].size() < min_value ) { min_value = CurDom[i].size(); min_index = i; } } return min_index; } bool have_d(int index , int d)//判断CurDom[index]域空间中是否有d { for(int i = 0 ;i temp; for(int j = 0 ;j temp_Assigned(int index,int d)//索引位置index中的d被选择后,行,列,方块中其他索引位置的域中有d值时将d删除掉 { int row = index/9; int col = index%9; vector temp; for(int i=0;i<9;i++) { int row_index = row*9+i; if(Assigned[row_index] == 0) { if(have_d(row_index,d)) { temp.push_back(row_index); remove_d(row_index,d); } } } for(int i=0;i<9;i++) { int col_index = i*9+col; if(Assigned[col_index] == 0) { if(have_d(col_index,d)) { temp.push_back(col_index); remove_d(col_index,d); } } } for(int i = row/3*3;i < row/3*3+3;i++) for(int j = col/3*3;j temp_Assigned_list, int d )//重新将被删除d的索引位置的域空间加回d { for(int i=0;i temp; temp.push_back(row); temp.push_back(col); temp.push_back(d); answer.push_back(temp);//先放入结果队列 Assigned[min_index] = d; vector temp_Assigned_list = temp_Assigned(min_index,d);//list,里面包含当前选择d约束时受影响的位置链表 if(GAC_Enforce() == true) { if(GAC(level-1))//空格数-1 { return true; } } Restore_CurDoms(temp_Assigned_list,d);//域空间重新放回d Assigned[min_index]=0; answer.pop_back(); } return false; } void print_map(int map[9][9]) { for(int i=0;i<9;i++) { cout<<"[ "; for(int j=0;j<9;j++) { cout<