算法第五章作业
- 实践题目名称:最小重量机器设计
- 用回溯法的方法分析“最小重量机器设计问题”
由题可知,需要在总价格不超过d的情况下利用回溯法找到最小重量的机器设计。
首先,初始化当前价格CurValue=0,当前重量CurWeight=0,所求得的最小重量MinWeight为一个相对较大值。还要设置一个bestx[101]数组来记录在计算出最小重量时对应每个部件的供应商情况。
在回溯法中循环选择第i号部件时,判断已购买部件价格之和CurValue与第i号机器价格之和是否不超过题目给出的最小价格d:CurValue+c[t][j]<=d,以及判断当前重量CurWeigh与第i号机器的重量是否小于最小重量MinWeight:CurWeight+w[t][j]<MinWeight。如果超过,则进行剪枝处理;如果不超过,则更新状态,让当前价格加上第i号部件的价格:CurValue=CurValue+c[t][i],当前重量加上第i号部件的重量:CurWeight=CurWeight+w[t][i],用数组x[i]记录当前部件的供应商。然后继续选择下一个供应商进行判断。
当找到叶子结点时(t>n),此时所有部件都已选择成功,判断当前重量CurWeight是否小于最小重量MinWeight,如果是的话就将当前重量CurWeight赋值给最小重量MinWeight,同时更新供应商情况bestx[i]。然后回溯到上一步,直到整个排列树都搜索完成。
-
说明“最小重量机器设计问题"的解空间
由题可知,一个机器由n个部件组成,而每一种部件都可以从m个不同的供应商购得,其可能解有m*m*m....m=(m)^n种。
以题目为例,该机器由3个部件组成,且这3个部件都可以从3个不同供应商购得,其解空间为{(1,1,1),(1,1,2),(1,1,3),(1,2,1),(1,2,2),(1,2,3),(1,3,1),(1,3,2),(1,3,3),(2,1,1),(2,1,2),(2,1,3),(2,2,1),(2,2,2),(2,2,3),(2,3,1),(2,3,2),(2,3,3),(3,1,1),(3,1,2),(3,1,3),(3,2,1),(3,2,2),(3,2,3),(3,3,1),(3,3,2),(3,3,3)}。
-
说明 “最小重量机器设计问题"的解空间树
-
在遍历解空间树的过程中,每个结点的状态值是什么
在遍历解空间树之前,每个结点应包含对应部件的重量weight与价格value。
在遍历解空间树后,如果满足约束条件当前部件价格CurValue加上当前结点对应的价格value不超过要求的总价格:CurValue+c[t][j]<=d,就更新该结点状态:让当前价格加上第i号部件的价格:CurValue=CurValue+c[t][i],当前重量加上第i号部件的重量:CurWeight=CurWeight+w[t][i],用数组x[i]记录当前部件的供应商。
for(int j=1;j<=m;j++){ //注意列数j是供应商 if(CurValue+c[t][j]<=d&&CurWeight+w[t][j]<MinWeight){ //保证最小重量&&总价格不超过d CurValue=CurValue+c[t][j]; //更新状态 CurWeight=CurWeight+w[t][j]; x[t]=j; //记录购买每个零件的供应商 backtrack(t+1); //继续进行深度优先搜索 CurValue=CurValue-c[t][j]; //回溯 CurWeight=CurWeight-w[t][j]; } }
-
你对回溯算法的理解
回溯法是在包含问题所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。在探索某一结点时,要判断该结点是否包含问题要求的解以及是否符合限界条件,如果不符合,则可进行剪枝处理,跳过对该结点为根节点的子树的搜索,逐层向其祖先结点进行回溯;如果符合,则继续按照深度优先搜索搜索,直到搜索至叶子结点。
此外,可以根据题目要求灵活搜索。如果题目要求问题任一解,那么只要利用回溯法找到任一个解就可以结束搜索;如果题目要求问题所有解时,这时就要对解空间树全部搜索一遍得到答案。
回溯法模板(根据题目灵活变动):
void Backtrack(int t) {//以深度优先的方式遍历第t层中的某棵子树 if(t>n) { Output(x); return; } if (……) { x[t]=1; Backtrack(t+1); } if (……) { x[t]=0; Backtrack(t+1); } }