为啥我的 N 个皇后问题的回溯解决方案不起作用?

Posted

技术标签:

【中文标题】为啥我的 N 个皇后问题的回溯解决方案不起作用?【英文标题】:Why isn't my backtracking solution for N queens problem working?为什么我的 N 个皇后问题的回溯解决方案不起作用? 【发布时间】:2020-10-20 07:43:14 【问题描述】:

这是当我通过传递 args: 0 和 board 从主函数调用它时返回的输出,其中 0 是要开始的行号,而 board 是填充零的 4x4 板:

9       1       1       1
1       1       9       1
1       1       1       1
1       0       1       1

注意:9表示女王,1表示被女王攻击的细胞,0是安全细胞,既没有女王也没有被女王攻击。

bool queen_placer(int row, std::vector<std::vector<int>> &board)

    if (row == board.size())
    
        return true;
    
    for (int col = 0; col < board[0].size(); col++)
    
        bool safe = is_valid(row, col, board); //is_valid returns true if the position doesn't contain any queen and is not attacked by any queen
        if (safe)
        
            board[row][col] = 9;
            value_assigner(row, col, board); //value assigner just assigns the attack values of the queen so placed
            if (queen_placer(row++, board))
            
                return true;
            
            else
            
                continue;
            
        
    
    return false;

【问题讨论】:

我没有看到任何回溯。递增 row 看起来也很奇怪,无论是递增本身还是将同一行再次传递给递归。 @molbdnilo 我尝试实现回溯,但也许我失败了。你能帮我指出我的错误并改正吗? 回溯涉及撤消导致失败的选择,但无论发生什么,您都坚持board[row][col] = 9; @molbdnilo 非常感谢您指出我的错误。在我放置皇后之前,我编辑了代码以创建 board_prev 保存状态,如果递归调用未返回 true,则将板恢复为 board_prev 状态。并且代码现在正在返回正确的解决方案。我不了解 Stack Overflow 行为准则,因为我是新手。我应该更新我的问题,说它已解决并编辑代码吗? @Dharman 哦,好吧,我不知道你不应该在这里这样做。我认为如果我让其他可能遇到类似问题的人知道解决方案已经找到,那么他们可能会得到帮助,但我完全忘记了我也可以将其作为答案发布,而不是污染原始问题。谢谢你纠正我:) 【参考方案1】:

您没有回溯 - 回溯涉及撤消导致失败的选择,但您的 board[row][col] 是永远的。

如果递归失败,你需要将板子恢复到之前的状态。

【讨论】:

【参考方案2】:

以下是解决此问题的正确代码,仅在第 9 行和第 21 行对原始代码进行了更改:

bool queen_placer(int row, std::vector<std::vector<int>> &board)

    if (row == board.size())
    
        return true;
    
    for (int col = 0; col < board[0].size(); col++)
    
        std::vector<std::vector<int>> board_prev = board; //Added line
        bool safe = is_valid(row, col, board); //is_valid returns true if the position doesn't contain any queen and is not attacked by any queen
        if (safe)
        
            board[row][col] = 9;
            value_assigner(row, col, board); //value assigner just assigns the attack values of the queen so placed
            if (queen_placer(row + 1, board))
            
                return true;
            
            else
            
                board = board_prev; //Added line
                continue;
            
        
    
    return false;

这是这段代码给出的输出:

1       9       1       1
1       1       1       9
9       1       1       1
1       1       9       1

【讨论】:

以上是关于为啥我的 N 个皇后问题的回溯解决方案不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

回溯:八皇后问题(蒟蒻)

n皇后问题中的回溯和递归(Python)

N皇后问题(递归回溯)

如何使用回溯法解决 M<N 时的 M 个皇后

回溯算法

DFS-回溯与剪枝-C - N皇后问题