[人工智慧]回溯演算法解數獨
阿新 • • 發佈:2019-02-10
今天在AI課上學了CSP,然後學了回溯演算法。所以就用回溯演算法來解數獨吧。
數獨問題可以把九九八十一個格簡化為81個變數,每一個變數可以取1-9的值,當然,一開始初始化的值是不可以改變的。然後呢,對於這個數獨呢,有3個約束條件:(1)每行數字不能重複;(2)每列數字不能重複;(3)每個3*3小區域內數字不能重複。
對於回溯演算法,其實就是窮舉,窮舉出每個格子,也就是每個變數可能的值,如果該賦值不滿足約束條件就回溯到上一個格進行下一個值的判斷,直到窮舉到最後一個格子,那就代表成功了。
程式碼如下:
#include <iostream> #include <vector> #include <algorithm> using namespace std; int a[9][9] = { {0,2,0,0,0,0,0,0,0}, {0,0,0,6,0,0,0,0,3}, {0,7,4,0,8,0,0,0,0}, {0,0,0,0,0,3,0,0,2}, {0,8,0,0,4,0,0,1,0}, {6,0,0,5,0,0,0,0,0}, {0,0,0,0,1,0,7,8,0}, {5,0,0,0,0,9,0,0,0}, {0,0,0,0,0,0,0,4,0} }; int assign[81]; void print(){ for(int i=0;i<9;i++){ for(int j=0;j<9;j++){ cout<<a[i][j]<<" "; } cout<<endl; } cout<<endl; } bool finish(int assign[]) { for(int i = 0; i < 81; i++) { if(a[i / 9][i % 9] == 0) { return false; } } return true; } bool judge(int x,int y){ for(int i=0;i<9;i++){ if(a[x][i]==a[x][y]&&i!=y) return false; } for(int i=0;i<9;i++){ if(a[i][y]==a[x][y]&&i!=x) return false; } for(int i=x/3*3;i<x/3*3+3;i++){ for(int j=y/3*3;j<y/3*3+3;j++){ if(a[i][j]==a[x][y]&&(i!=x||j!=y)) return false; } } return true; } //int v = 0; void BT(int level) { int v = 0; if(finish(assign) == true) { print(); return; } while(assign[v] != 0) { v += 1; } //cout<<v<<endl; if(assign[v] != 2) { assign[v] = 1; for(int i = 1; i <= 9; i++) { a[v / 9][v % 9] = i; bool constraintsOK = true; if(judge(v / 9, v % 9) == false) { constraintsOK = false; } if(constraintsOK == true) { //print(); //system("pause"); BT(level + 1); } } a[v / 9][v % 9] = 0; assign[v] = 0; //cout<< level<<endl; return; } } int main() { for(int i = 0; i < 81; i++) { if(a[i / 9][i % 9] != 0) { assign[i] = 2; } else { assign[i] = 0; } } BT(0); //cout<< finish(assign)<<endl; }