标签:style blog color io 数据 for 问题 div
递归回溯
由于回溯法是对解空间的深度优先搜索,因此在一般情况下可用递归函数来实现回溯法如下:
t表示递归深度,即当前扩展节点在解空间树的深度。
n用来控制递归深度。当t>n时表示算法搜索到叶节点。
void backtrack( int t )
{
if ( t>n )
output(x);
else
for( int i=f(n,t); i<=g(n,t); i++ ) {
x[t]=h(i);
if ( constraint(t)&&bound(t) )
backtrack(t+1);
}
}
迭代回溯
采用树的非递归深度优先遍列算法,可将回溯法表示为一个非递归迭代过程。
solution(t)判断当前扩展节点是否得到问题的可行解。
void iterativeBacktrack( )
{ int t=1;
while ( t>0 ) {
if ( f(n,t)<=g(n,t) )
for( int i=f(n,t); i<=g(n,t); i++ ) {
x[t]=h(i);
if ( constraint(t)&&bound(t) ) {
if ( solution(t) ) output(x);
else t++; }
}
else t--;
}
}
用回溯法搜索子集树的一般算法描述为:
void backtrack( int t )
{
if ( t>n )
output(x);
else
for( int i=0; i<=1; i++ ) {
x[t]=i;
if ( constraint(t)&&bound(t) )
backtrack(t+1);
}
}
用回溯法搜索排列树的一般算法描述为:
void backtrack( int t )
{
if ( t>n )
output(x);
else
for( int i=t; i<=n; i++ ) {
swap(x[t], x[i] );
if ( constraint(t)&&bound(t) )
backtrack(t+1);
swap(x[t], x[i] );
}
}
public class Loading { //类的数据成员 static int n; //集装箱数 static int[] w; //集装箱重量数组 static int c; //第一艘轮船的载重量 static int cw; //当前载重量 static int bestw; //当前最优载重量 public static int maxLoading ( int [] ww, int cc ) { //初始化类数据成员 n=ww.length – 1; w=ww; c=cc; cw=0; bestw=0; //计算最优载重量 backtrack(1); return bestw; } //回溯算法 private static void backtrack( int t ) { //搜索第i层节点 if ( i>n ) { //到达叶节点 if (cw>bestw) bestw=cw; return; } //搜索子树 if (cw+w[I]<=c) { //搜索左子树,即x[i]=1 cw+=w[i]; backtrack(i+1); cw-=w[i]; } backtrack(t+1); //搜索右子树 } }
public class Loading { //类的数据成员 static int n; //集装箱数 static int[] w; //集装箱重量数组 static int c; //第一艘轮船的载重量 static int cw; //当前载重量 static int bestw; //当前最优载重量 static int r; //剩余集装箱的重量 public static int maxLoading ( int [] ww, int cc ) { //初始化类数据成员 n=ww.length – 1; w=ww; c=cc; cw=0; bestw=0; //初始化 for(int i=1; i<=n; i++) r+=w[i]; //计算最优载重量 backtrack(1); return bestw; } //回溯算法 private static void backtrack( int t ) { //搜索第i层节点 if ( i>n ) { //到达叶节点 if (cw>bestw) bestw=cw; return; } //搜索子树 r - = w[i]; if (cw+w[i]<=c) { //搜索左子树 cw+=w[i]; backtrack(i+1); cw -=w[i]; } if (cw+w[i]>bestw) //搜索右子树 backtrack(t+1); r + = w[i]; } }
构造最优解 public class Loading { //类的数据成员 static int n; //集装箱数 static int[] w; //集装箱重量数组 static int c; //第一艘轮船的载重量 static int cw; //当前载重量 static int bestw; //当前最优载重量 static int r; //剩余集装箱的重量 static int[] x; //当前解 static int[] bestx; //当前最优解 public static int maxLoading ( int [] ww, int cc ) { //初始化类数据成员 n=ww.length – 1; w=ww; c=cc; cw=0; bestw=0; x=new int[n+1]; bestx=xx; //初始化 for(int i=1; i<=n; i++) r+=w[i]; //计算最优载重量 backtrack(1); return bestw; } //回溯算法 private static void backtrack( int t ) { //搜索第i层节点 if ( i>n ) { //到达叶节点 for( int j=1; j<=n; j++ ) bestx[j]=x[j]; bestw=cw; return; } //搜索子树 r - = w[i]; if (cw+w[i]<=c) { //搜索左子树 x[i]=1; cw+=w[i]; backtrack(i+1); cw -=w[i]; } if (cw+w[i]>bestw) { //搜索右子树 x[i]=0; backtrack(t+1); } r + = w[i]; }
迭代回溯
由于数组x记录了解空间从根节点至当前扩展节点的路径,这些信息已包含了回溯法所需的信息。利用数组x的信息可以改为非递归的形式。
标签:style blog color io 数据 for 问题 div
原文地址:http://www.cnblogs.com/ajucs/p/3913594.html