装载问题
用***回溯法***解装载问题时
算法Maxloading调用递归函数Backtrack(1)实现回溯搜索。Backtrack(i)搜索子集树中第i层子树。
类Loading的数据记录子集树中结点信息,以减少传给Backtrack的参数。cw记录当前结点所相应的装载重量,bestw记录当前最大装载重量。
在算法Backtrack中,当i>n时,算法搜索至叶节点,其相应的装载重量为cw。如果cw>bestw,则表示当前解优于当前最优解,此时应更新bestw。当i<=n时,当前扩展结点Z是子集树中的内部节点。该结点有x[i]=1和x[i]=0两个儿子结点。其左儿子结点表示x[i]=1的情形,仅当cw+w[i] <=c时进入左子树,对左子树进行递归搜索。其右儿子结点表示x[i]=0的情形。由于可行结点的右儿子结点总是可行的,故进入右子树时不需要检查可行性。
template<class Type>
class Loading{
friend Type MaxLoading(Type c,Type w[],int n, int bestx[]);
private:
void Backtrack(int i);
int n, *x, *bestx;
Type *w, c, cw, bestw, r;
}
template<class Type>
void Loading<Type>::Backtrack(int i){
if(i>n){
if(cw>bestw){
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+r>bestw){
x[i]=0;
Backtrack(i+1);
}
r+=w[i];
}
template<class Type>
void MaxLoading(Type c,Type w[],int n, int bestx[]){
Loading<Type>X;
X.c=c;X.w=w;X.n=n;X.bestx=bestx;
X.x=new int[n+1];X.cw=0;X.bestw=0;X.r=0;
for(int i=1;i<=n;i++)
X.r+=w[i];
X.Backtrack(1);
delete[]X.x;
return X.bestx;
}