跳转至

回溯算法

设我们已经有一个部分解 \((x_1, \dots, x_i)\),满足 \(\forall 1 \le k \le i < n, x_k \in S_k\),然后我们添加 \(x_{i+1} \in S_{i+1}\),并检查 \((x_1, \dots, x_i, x_{i+1})\) 是否满足约束条件。若满足,则继续添加下一个 \(x\),否则删除当前 \(x_{i+1}\) 并尝试下一个 \(x_{i+1}\)。若所有的 \(x_{i+1} \in S_{i+1}\) 均不满足条件,则删除 \(x_i\) 并回溯到上一个部分解 \((x_1, \dots, x_{i-1})\)

回溯算法的伪代码为:

bool Backtracking(int i) {
    Found = false;
    if (i > N)
        return true;  /* solved with (x1, …, xN) */
    for (each xi in Si) { 
        /* check if satisfies the restriction R */
        OK = Check((x1, , xi) , R);  /* pruning */
        if (OK) {
            Count xi in;
            Found = Backtracking(i + 1);
            if (!Found) Undo(i);  /* recover to (x1, …, xi-1) */
        }
        if (Found) break; 
    }
    return Found;
}