课程设计说明书设计题目:最小重量机器设计问题专业:班级:设计人:山东科技大学2012年12月20日课程设计任务书学院:专业:班级:姓名:一、课程设计题目:最小重量机器设计问题二、课程设计主要参考资料(1)(2)三、课程设计应解决的主要问题(1)(2)(3)四、课程设计相关附件(如:图纸、软件等):(1)(2)五、任务发出日期:2013-11-21课程设计完成日期:2013-12-20指导教师签字:系主任签字:指导教师对课程设计的评语成绩:指导教师签字:年月日二分查找程序的实现一、设计目的1、了解分支限界法的基本思想2、运用分支限界法解决最小重量机器设计问题二、设计要求1、问题描述:设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格,给出总价格不超过d的最小重量机器设计。三、设计说明(一)、需求分析1、分支限界法的基本思想分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。2、常见的两种分支限界法(1)队列式(FIFO)分支限界法按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。数据结构:队列(2)优先队列式分支限界法按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。数据结构:堆最大优先队列:使用最大堆,体现最大效益优先最小优先队列:使用最小堆,体现最小效益优先3、分支限界法与回溯法的不同(1)求解目标:回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。(2)搜索方式的不同:回溯法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树。4、优先队列式分支限界法程序框架设T为状态空间树的根结点:~C(x)为消耗估计函数;初始化优先队列Q计算~C(T),并将T入队;循环,直到队列Q空(无解);结点e出队;若e是回答结点,则输出解或求解路径,求解结束;否则,检查e的子结点x;若x满足约束条件,则计算~C(x),并将x入队;记录搜索路径;(二)、概要设计1、设计思路:解空间为一棵排列树,采用优先队列式分支限界法找出所给的最小重量机器设计,开始时,将排列树的根节点置为当前扩展结点。在初始扩展结点处还设有选定部件是哪个供应商提供的,故cv=0,cw=0,position=0,peer=0,1≤i≤n。x[1:n]记录供应商的选择while完成对排列树内部结点的有序扩展。循环体内依次从活结点优先队列中取出具有最小重量的结点,依次为当前扩展结点。并且花费不超过c并加以扩展,队列为空时则结束循环。当peer=n时,此时扩展结点是叶节点,得到当前的最小重量和最优解数组x。2、优先级的设定:优先级的设定,当队列中有两个结点的重量是相同的时候,那么设定为,level大的优先级就更高一点,也就是说,更接近于叶子结点的那个结点更优先。目的就是为了更快的刷新出最小的重量,方便后面的剪枝。如果说没有两个结点重量相同,那就重量更小的优先。优先级优化思路:类似于旅行售货商问题的优先级设定,记录剩余的未购买原件中的,单个原件购买的最小价值之和。(三)、详细设计#includeiostream#includequeue#defineINT_MAX100usingnamespacestd;int**c=NULL;int**w=NULL;intminValue;//最小重量intn,m,d;//n表示供应商个数,m表示零件个数,d表示价格上限classNode{//优先队列的结点public:Node(){};intweight;//质量intval;//价格intsource;Node*father;//父结点intt;booloperator(constNode&other)const{//重写比较运算符if(tother.t){returntrue;}elseif(t==other.t){if(weightother.weight){returntrue;}elsereturnfalse;}elsereturnfalse;}};Node*minLeaf;voidminMacWei(){Nodeinitial;initial.father=NULL;initial.weight=0;initial.val=0;initial.t=0;initial.source=0;priority_queueNodeHeap;Heap.push(initial);while(!Heap.empty()){Node*fartherNode=newNode(Heap.top());Heap.pop();if(fartherNode-t==n){if(fartherNode-valminValue){minValue=fartherNode-val;minLeaf=fartherNode;}}else{for(inti=1;i=m;++i)//依次选择孩子结点{if(fartherNode-weight+w[fartherNode-t+1][i]=d)//左子树{Node*newNode=newNode;newNode-t=fartherNode-t+1;newNode-father=fartherNode;newNode-source=i;newNode-weight=fartherNode-weight+w[newNode-t][i];newNode-val=fartherNode-val+c[newNode-t][i];Heap.push(*newNode);}}}}};intmain(){cout请输入供应商个数:;cinn;cout请输入零件个数:;cinm;cout请输入价格上限:;cind;c=newint*[n+1];w=newint*[n+1];minValue=INT_MAX;minLeaf=NULL;for(inti=0;i=n;++i){c[i]=newint[m+1];w[i]=newint[m+1];}for(inti=1;i=n;++i){for(intj=1;j=m;++j){cout第i个供应商的第j个零件的价格为:;cinc[i][j];}}for(inti=1;i=n;++i){for(intj=1;j=m;++j){cout第i个供应商的第j个零件的质量为:;cinw[i][j];}}minMacWei();cout最小重量为:minValueendl;for(inti=0;i=n;++i){deletec[i];deletew[i];}deletec;deletew;return0;}四、运行结果及分析算法时间复杂度:程序中最大的循环出现在函数minMacWei()中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。五、总结通过这次实验我了解到分支限界法是一种在问题的解空间树上搜索问题解的算法。分支限界法的搜索策略是,在扩展结点处,先生成其所有的儿子结点,然后再从当前的活结点中选择下一个扩展结点。为了有效的选择下一个扩展结点,以加速搜索的进程,在每一个结点处,计算一个函数值,并根据这个以计算出的函数值,从当前结点中选择一个最有利的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解。这些算法思想可以用于其它许多问题的求解。