尽管不存储状态,但Sudoku求解器的这种实现如何工作?

时间:2016-07-18 01:35:21

标签: c++ recursion pass-by-reference backtracking recursive-backtracking

This链接具有Sudoku Solver算法的Backtracking实现。注意如果最初分配的值没有给出有效输出,行号42如何将最初分配给单元格的值恢复为另一个值。

但是,我不明白仅仅改变那个细胞的价值就足够了。这个调用可以触发许多其他调用,而因为数组(矩阵)由内存(引用)传递,它不保留矩阵的副本(grid [N] [N] )在递归函数的每次调用时,所以更改直到递归的基本情况,即使在递归的第一个递归帧中也会反映出来。

据我所知,在调用递归函数之前,你应该制作一个grid [N] [N]的临时副本,并在调用返回后立即恢复,并在调用同一帧中的下一个函数之前恢复它

这样的东西
for (int num = 1; num <= N; num++)
    {
        // if looks promising
        if (isSafe(grid, row, col, num))
        {
            //save grid state
            int[][] temp = new int[N][N];
            save(temp,grid); //copy all values from grid to temp             

            // make tentative assignment
            grid[row][col] = num;

            // return, if success, yay!
            if (SolveSudoku(grid))
                return true;

            //restore grid state           
            restore(temp,grid); //copy all values from temp back to grid

            // failure, unmake & try again
            grid[row][col] = UNASSIGNED;
        }
    }

请帮助我理解这个细节。

1 个答案:

答案 0 :(得分:3)

保存状态:每次递归调用都会在调用堆栈中保存状态。

修改网格的未分配部分,直到找到有效的解决方案。一旦完成,所有堆叠的函数调用都将终止(第38和39行),使grid[][]处于解决状态。如果不是,则将当前单元格恢复为其UNASSIGNED值并尝试下一个可能的值。

这是一个蛮力解算器。您可能也想围绕它进行谷歌搜索。

希望这有帮助。