数独一代:循环 我试图引用数独生成器算法,这是我的C++代码: void generateSudoku(num sudoku[][N]) { int i,j,k; int vett[N],n,old; //clean the sudoku matrix filling it with -1 for(i=0;i<N;i++) for(j=0;j<N;j++) sudoku[i][j].val=-1; //generate the sudoku for(i=0;i<N;){ for(j=0;j<N;){ k=0; clean(vett,N); //fills the vector with -1 old=sudoku[i][j].val; //saves the actual value do{ if(k<9){ do{ n=rand()%9+1; }while(find(vett,N,n)); //generate n while it already exists in vett vett[k++]=n; if((!(exists(sudoku,i,j,n))) && (n!=old)){ //if it not exists on row, column and sub-matrix and it's different between the old value, it's OK sudoku[i][j++].val=n; if(j==N) i++; k=10; } } else{ sudoku[i][j].val=-1; if(j>0) j--; else if(i>0){ j=N-1; i--; } k=10; } }while(k<=9); } } }

数独一代:循环 我试图引用数独生成器算法,这是我的C++代码: void generateSudoku(num sudoku[][N]) { int i,j,k; int vett[N],n,old; //clean the sudoku matrix filling it with -1 for(i=0;i<N;i++) for(j=0;j<N;j++) sudoku[i][j].val=-1; //generate the sudoku for(i=0;i<N;){ for(j=0;j<N;){ k=0; clean(vett,N); //fills the vector with -1 old=sudoku[i][j].val; //saves the actual value do{ if(k<9){ do{ n=rand()%9+1; }while(find(vett,N,n)); //generate n while it already exists in vett vett[k++]=n; if((!(exists(sudoku,i,j,n))) && (n!=old)){ //if it not exists on row, column and sub-matrix and it's different between the old value, it's OK sudoku[i][j++].val=n; if(j==N) i++; k=10; } } else{ sudoku[i][j].val=-1; if(j>0) j--; else if(i>0){ j=N-1; i--; } k=10; } }while(k<=9); } } },c++,algorithm,sudoku,C++,Algorithm,Sudoku,在本例中,它继续生成6-1,然后在有*的地方生成1-6,并且它永远不会结束。但即使我解释了它循环的原因,我也不知道纠正它的最佳方法。有人能帮帮我吗?你得进一步回溯。第二行的最后一个单元格中没有有效项。我不确定贪婪算法是否能作为数独生成器工作。我会尝试使用基于堆栈树的方法。以下可能会有所帮助(未经测试): 无效恢复(标准::向量&v){ v、 清除(); 对于(int i=0;i!=9;++i){ v、 推回(1+i); } } void生成(int(&数独)[9][9]) { 标准::向量允许符

在本例中,它继续生成6-1,然后在有*的地方生成1-6,并且它永远不会结束。但即使我解释了它循环的原因,我也不知道纠正它的最佳方法。有人能帮帮我吗?

你得进一步回溯。第二行的最后一个单元格中没有有效项。我不确定贪婪算法是否能作为数独生成器工作。我会尝试使用基于堆栈树的方法。

以下可能会有所帮助(未经测试):

无效恢复(标准::向量&v){ v、 清除(); 对于(int i=0;i!=9;++i){ v、 推回(1+i); } } void生成(int(&数独)[9][9]) { 标准::向量允许符号[9][9]; 布尔成功=真; 对于(int i=0,j=0;i!=9;){ 如果(成功){ 恢复(允许符号[i][j]); 成功=错误; } 而(!allowedSymbols[i][j].empty()){ int index=rand()%允许符号[i][j].size(); 如果(!exists(数独,i,j,allowedSymbols[i][j][index]){//如果它不存在于行、列和子矩阵上,则可以 成功=正确; 打破 } allowedSymbols[i][j]。擦除(allowedSymbols[i][j]。开始()+索引); } 如果(成功){ ++j; 如果(j==9){ j=0; ++一,; } }否则{ //回溯。 --j; 如果(j==-1){ j=8; --一,; } allowedSymbols[i][j]。擦除(标准::查找(allowedSymbols[i][j]。开始(), 允许符号[i][j].end(), 数独[i][j]); } } }
您应该存储禁止的值,在这里您只能回溯一个级别。我认为应该使用一个数组来存储所有禁止值的每个值,但我不确定它是否有效。当我应该清理向量时?你可以每次清理3行完全填充。我尝试了:
if(!(exists(sudoku,I,j,n))&&(!find(sudoku[I][j].old,n,n)){sudoku[I][j++].val=n;sudoku[I][j].old[sudoku I][j]=n;if(j==n)I++;k=10;
2 7 6 | 9 1 3 | 4 5 8
4 3 9 | 5 7 2 | * *
void restore(std::vector<int>& v) {
    v.clear();
    for (int i = 0; i != 9; ++i) {
        v.push_back(1 + i);
    }
}

void generate(int (&sudoku)[9][9])
{
    std::vector<int> allowedSymbols[9][9];

    bool succeed = true;
    for(int i = 0, j = 0; i != 9; ) {
        if (succeed) {
            restore(allowedSymbols[i][j]);
            succeed = false;
        }
        while (!allowedSymbols[i][j].empty()) {
            int index = rand() % allowedSymbols[i][j].size();

            if (!exists(sudoku, i, j, allowedSymbols[i][j][index])) { //if it not exists on row, column and sub-matrix, it is OK
                succeed = true;
                break;
            }
            allowedSymbols[i][j].erase(allowedSymbols[i][j].begin() + index);
        }
        if (succeed) {
            ++j;
            if (j == 9) {
                j = 0;
                ++i;
            }
        } else {
            // backtrack.
            --j;
            if (j == -1) {
                j = 8;
                --i;
            }
            allowedSymbols[i][j].erase(std::find(allowedSymbols[i][j].begin(),
                                                 allowedSymbols[i][j].end(),
                                                 sudoku[i][j]));
        }
    }
}