跳转至

剪枝(Pruning)

剪枝是一种在搜索算法(如 DFS、BFS、回溯)中提前排除不可能或不优的分支,从而减少搜索空间、提高效率的技巧。

基本思想

  • 在搜索过程中,判断当前状态是否有可能得到更优解或满足条件。
  • 如果不可能,则提前终止该分支的搜索(即“剪掉”)。
  • 剪枝可以显著降低时间复杂度,避免无效递归或枚举。

常见应用

  • 回溯算法(如排列组合、数独、八皇后等)
  • 状态空间搜索(如博弈、路径规划)
  • 动态规划中的状态转移优化

伪代码

function dfs(state):
    if 不满足条件或无解:
        return
    if 到达目标状态:
        更新答案
        return
    for 每个可能的选择:
        if 可以剪枝:
            continue
        dfs(新状态)

代码示例(八皇后问题中的剪枝)

#include <vector>
using namespace std;

int n, ans = 0;
vector<bool> col, diag1, diag2;

void dfs(int row) {
    if (row == n) { ans++; return; }
    for (int c = 0; c < n; ++c) {
        if (col[c] || diag1[row + c] || diag2[row - c + n]) continue; // 剪枝
        col[c] = diag1[row + c] = diag2[row - c + n] = true;
        dfs(row + 1);
        col[c] = diag1[row + c] = diag2[row - c + n] = false;
    }
}

int main() {
    n = 8;
    col.assign(n, false);
    diag1.assign(2 * n, false);
    diag2.assign(2 * n, false);
    dfs(0);
    // ans 即为解的数量
}

注意事项

  • 剪枝条件需保证正确性,不能剪掉可能的最优解。
  • 剪枝越充分,搜索越快,但要注意实现复杂度和边界情况。

发现错误?想一起完善? 在 GitHub 上编辑此页

本文档内容作为个人算法笔记整理,代码模板可按需要参考和修改。