回溯法
主要思想:
利用深度优先搜索(DFS)作为算法实现的主要思想,配合限界条件进行剪枝,来减小空间的占有量。限界条件分为显式限界与隐式限界两种(后面会说)。
运用步骤:
伪代码范式:
backtrack ( int i )//i为当前递归的深度
{
if( i > n ) {
output/record;
return;
}//到达叶子节点,判断是否输出或者记录
else{
if( x[i]不满足显式限界条件 ){
记录x[i];
backtrack( i+1);
清除记录x[i];
}//左孩子
else if ( x[i] 不满足隐式限界条件 ){
backtrap ( i + 1 );
}//右孩子
}
}
限界条件:
限界条件分为两种:
1. 显式限界条件
显示限界条件为题目中已经给出的,具有明显说明的条件,或者是常识:
例如:
- 0/1背包中,显式限界条件为:
cur_weight + w[i] > weight
意味当前质量加上当前物品质量大于背包总重量,即无法放入当前物品,就剪枝,不展开当前子树。 - 8-皇后问题中,显式限界条件为:
x[i] = { 0 , 1 ,2 ,…};
意味着最后输出的矩阵中,只能是整数。
2. 隐式限界条件
隐式限界条件,是为了剪枝,缩小储存空间与运行时间,自己定义的启发式的限界条件:
例如:
- 0/1背包:
cur_value + bound <= bestv
意味着子树能达到的价值上限比当前的最优价值小,因此剪枝,不继续展开。 - 8-皇后问题:
棋子不在同一对角线,也不在同一行,同一列
题目中给出。
具体实例:
8-皇后问题:
链接: link.
货箱装载问题
链接: link
图的m着色问题
链接:link