问答题 阅读下列说明和C代码,将应填入空白处的语句补充完整。
[说明]
设某一机器由n个部件组成,每一个部件都可以从m个不同的供应商处购得。供应商j供应的部件i具有重量W ij 和价格C ij 。设计一个算法,求解总价格不超过上限cc的最小重量的机器组成。
采用回溯法来求解该问题。
首先定义解空间。解空间由长度为n的向量组成,其中每个分量取值来自集合{1,2,…,m},将解空间用树形结构表示。
接着从根节点开始,以深度优先的方式搜索整个解空间。从根节点开始,根节点成为活节点,同时也成为当前的扩展节点。向纵深方向考虑第1个部件从第1个供应商处购买,得到一个新节点。判断当前的机器价格(C 11 )是否超过上限(cc),重量(W 11 )是否比当前已知的解(最小重量)大,若是,应回溯至最近的一个活节点;若否,则该新节点成为活节点,同时也成为当前的扩展节点,根节点不再是扩展节点。继续向纵深方向考虑第2个部件从第1个供应商处购买,得到一个新节点。同样判断当前的机器价格(C 11 +C 21 )是否超过上限(cc),重量(W 11 +W 21 )是否比当前已知的解(最小重量)大。若是,应回溯至最近的一个活节点;若否,则该新节点成为活节点,同时也成为当前的扩展节点,原来的节点不再是扩展节点。以这种方式递归地在解空间中搜索,直到找到所要求的解或者解空间中已无活节点为止。
下面是该算法的C语言实现。
(1)变量说明
n:机器的部件数
m:供应商数
cc:价格上限
w[][]:二维数组,w[i][j]表示第j个供应商供应的第i个部件的重量
c[][]:二维数组,c[i][j]表示第j个供应商供应的第i个部件的价格
bestW:满足价格上限约束条件的最小机器重量
bestC:最小重量机器的价格
bestX[]:最优解,一维数组,bestX[i]表示第i个部件来自哪个供应商
cw:搜索过程中机器的重量
cp:搜索过程中机器的价格
x[]:搜索过程中产生的解,x[i]表示第i个部件来自哪个供应商
i:当前考虑的部件,从0到n-1
j:循环变量
(2)函数backtrack
int n=3;
int m=3;
int cc=4;
int w[3][3]={{1, 2, 3}, {3, 2, 1}, {2, 2, 2}};
int c[3][3]={{1, 2, 3}, {3, 2, 1}, {2, 2, 2}};
int bestW=8;
int bestC=0;
int bestX[3]={0, 0, 0};
int cw=0;
int cp=0;
int X[3]={0, 0, 0};
int backtrack(int i){
int j=0;
int found=0;
if(i>n-1){ /*得到问题解*/
bestW=cw;
bestC=cp;
for(j=0; j<n; j++){
______;
}
return 1;
}
if(cp<=cc){ /*有解*/
found=1;
}
for(j=0; ______; j++){
/*第i个部件从第j个供应商购买*/
______;
cw=cw+w[i][j];
cp=cp+c[i][i][j];
if(cp<=cc&&______ {/*深度搜索,扩展当前节点*/
if(backtrack(i+1)){found=1;}
}
/*回溯*/
cw=cw-w[i][j];
______;
}
return found;
}
【正确答案】
【答案解析】bestX[j]=x[j]
j<m
x[i]=j
cw<bestW
cp=cp-c[i][j] 本题考查回溯法的应用。
在题目的描述中告诉了我们回溯法的基本思想。其实回溯法主要有两个过程,一个是向前探索,只要在当前满足设定的判定条件时,才向前探索,而另外一个就是回溯,在两种情况下,需要回溯,其分别是当不满足设定条件时和求的一个解的时候。
下面我们来具体分析本试题。根据题目给出的注释,我们知道第1空所处的位置是得到问题的一个解时,我们该怎么办,根据题目描述,应该是将这个解记录下来,存放到bestX数组当中,而求得的解是保存在x数组当中的,因此这里需要循环将x数组中的元素值赋给bestX数组,因此第1空答案为bestX[j]=x[j]。
第2空是for循环中的循环判定条件,根据题目注释我们知道该循环的作用是确定第i个部件从第i个供应商购买,那么在确定第i个部件到底是从哪个供应商购买时,需要比较从各供应商购买的情况,因此循环的次数为供应商数,因此第2空答案是i<m。结合这个循环体当中的语句和我们对回溯法的理解,我们可以发现循环下面的语句是要考虑将第i个部件从供应商i购买,也就是j是当前解的一部分,因此需要将i记录到解当中来,所以第3空应该是x[i]=i。
第4空是if语句中的一个条件,根据题目注释,我们可以知道如果该if语句表达式的计算结果为真,需要进行深度搜索,扩展当前节点,那么如果要继续向前探索,就需要满足设定的条件,也就是当前总重量要小于bestW,而当前总价格要小于等于cc,因此第4空的答案应该填cw<bestW。
根据题目注释,第5空是在回溯下面的语句,根据回溯的原则我们可以知道,回溯时,要将当前考虑的节点的重量和价格从总重量和总价格中减去,因此第5的答案是cp=cp-c[i][j]。