基于回溯法的最小重量机器设计问题算法设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于回溯法的最小重量机器设计问题算法设计
1.问题描述
设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。
设wij是从供应商j处购得的部件i的重量,cij是相应的价格。
试设计一个算法,给出总价格不超过c的最小重量机器设计。
2.方法简介
回溯法是一个既带有系统性又带有跳跃性的搜索算法,可以系统的搜索问题的所有解。
回溯法在问题的解空间树中,按深度优先策略,从根节点出发搜索解空间树。
算法搜素至解空间的任一结点时,先判断该结点是否包含问题的解。
如果肯定不包含,则跳过对以该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜素。
回溯法求问题的所有解时,要回溯到根,且根节点的所有子树都被搜索遍才结束。
回溯法求问题的一个解时,只要搜索到问题的一个解就可结束。
2.1回溯法的思想
用回溯法解问题时,要明确定义问题的解空间和组织结构。
问题的解空间应至少包含问题的一个(最优)解。
通常回溯法的组织结构为树或图。
2.1.1用回溯法解决问题的步骤:
1.定义问题的解空间。
例如:对于有n种可选择物品的0-1背包问题,其解空间由长度为n的0-1向量组成。
该解空间包含对变量的所有0-1赋值。
当n=3时,其解空间是:
{(0,0,0,),(0,0,1),(0,1,0),(0,1,1,),(1,0,0),(1,0,1),(1,1,0),(1,1,1,)}
2.组织解空间。
将解空间组织成树或图或其他形式,使得能用回溯法很好的搜索整个解空间。
3.以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。
2.1.2解空间的搜索方法:
1.从开始结点(根结点)出发,将开始结点作为活结点,同时作为当前的扩展节点。
2.在当前扩展结点处,搜索向纵深方向移至一个新结点。
3.新结点成为新的活结点,并成为当前扩展结点。
4.若在当前扩展结点处不能再向纵深方向移动,当前扩展节点成为死结点。
5.从该死结点往回移至最近的活结点处,将这个活结点作为当前的扩展结点。
6.以上述步骤在解空间搜索,直至找到所要求的解空间或解空间中已无活结点为止。
总结:在搜索过程中遇到活结点继续纵深向下搜索,遇到死结点向上搜索。
3.问题分析
3.1子集树与排列树
子集树:当所给问题是从n个元素的集合S中找出S满足某种性质的子集时,相应的解空间树成为子集树。
排列树:当所给问题是确定n个元素满足某种性质的排列时,相应的解空间树称为排列树。
3.2实例分析
在最小重量机器设计问题中,设n为3,m为2。
即该问题为:某一机器由3个部件组成,每一种部件都可以从2中不同的供应商处,1供应商或者2供应商处购得。
找出出购得机器的总价格不超过c,且机器重量最小的方案。
供应商与部件间的价格关系如表3-1所示,供应商与部件间的重量关系如表3-2所示。
表3-1 供应商与部件间的价格关系
表3-2 供应商与部件间的重量关系
在此问题中,解空间为{(1,1,1),(1,1,2),(1,2,1),(2,1,1),(1,2,2),(2,1,2),(2,2,1),(2,2,2)}
通过解空间即可确定组织结构为树,且是一棵子集树。
如图3-1所示。
图3-1
解空间树的第i层到第i+1层边上的标号给出了变量的值。
从树根到叶的任一路径表示解空间中的一个元素。
例如,从根结点到结点H的路径相应于解空间中元素(1,1,1)。
假设要求总价格不超过4的最小机器重量方案。
通过上述解空间可得从不同供应商处购得机器的价格集合为c={4,4,6,5,6,5,7,7},对应的机器重量集合为w={6,7,7,7,8,8,8,9}。
通过比较可得满足机器总价格不超过4的解有两种{(1,1,1,),(1,1,2)},通过比较两个解得到满足要求的最小机器重量为6,即该问题的解为(1,1,1,),也就是从1供应商处购买部件1,部件2,部件3。
3.3具体分析
通过上述的具体实例,我们可以得出最小重量机器设计问题是一个子集问题。
某一机器的n个部件可以从m个不同的供应商处购得,即可以有m n个不同的购买方案。
i∈[1,n],j∈[1,m],则购买到的机器的总价格为∑cij,i∈[1,n],j∈[1,m], 机器的总重量为∑wij,i∈[1,n],j∈[1,m]。
则求该问题的解可转化为求:
∑cij≤c, i∈[1,n],j∈[1,m]
且min∑wij, i∈[1,n],j∈[1,m]
将所以选用子集树来搜索该问题的最优解,除了叶子节点外,每个结点下均有m个结点。
题目已经给出总价格的上限,因此算法通过使用回溯来选择合适的机器使得在总价格不超过c时得到的机器重量最小。
首先初始化当前价格dc=0,当前重量dw=0。
设置一个变量sum 表示选择机器的总重量,初始化其为每个部件从1号供应商购买的重量。
在循环选择i号机器时,判断从j号供应商购买机器后的价格是否大于总价格,如果不大于则选择,否则不选,继续选择下一供应商进行判断。
在得到一个合适的供应商后,继续选择下一机器的供应商,从第一个选到最后一个供应商。
当所有机器选择结束后,判断得到的总重量是否比之前的sum小,如果小就赋给sum,然后从这一步开始,回溯到上一机器,选择下一合适供应商,继续搜索可行解,直到将整个树搜索完毕。
这样,最终得到的sum即为最优解。
选择一个剪枝条件,在每次选择某一机器时,判断选择后的当前重量是否已经大于之前的sum,如果大于就不用继续搜索。
4.算法及算法分析
算法设计:
1.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,c为总价格的上限。
2.用递归函数backtrack(i)来实现回溯法搜索树,形式参数i表示递归深度。
①若dc>c,是不满足要求的解,剪去相应子树,返回到i-1层继续执行。
②若dw>=sum,就不是题目要求的最优解,剪去相应子树,返回到i-1层继续执行。
③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行;
④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。
算法:
void backtrack(int i){
if(i>n){
if(dw<sum)
sum = dw;
return;
}
for(int j=1;j<=m;j++){
dw+=w[i][j];
dc+=c[i][j];
if(dw<sum && dc<=d){
k[i]=j;
backtrack(i+1);
}
dw-=w[i][j];
dc-=c[i][j];
}
}
5.实现
输入数据3 2 4 2 3 1 3 1 1 2 3 1 2 3 4。