最小重量机器设计问题+工作分配问题
(完整word版)最小重量机器设计问题

最小重量机器设计问题1。
问题描述设某一机器由n个部件组成,每一个部件都可以从m个不同的供应商处购得。
设wij是从供应商j处购得的部件i的重量,cij是相应的价格。
试设计一个算法,给出总价格不超过c的最小重量机器设计.算法设计:对于给定的机器部件重量和机器部件价格,计算总价格不超过d的最小重量机器设计。
2.算法流程分析设开始时bestx=[-1,—1,…,—1]则相应的排列树由x[0:n—1]的所有排列构成。
找最小重量机器设计的回溯算法Backtrack是类machine的公有成员。
私有数据成员整型数组Savex保存搜索过的路径,到达叶节点后将数据赋值给数组bestx。
成员bestw记录当前最小重量,cc表示当前花费,cw表示当前的重量。
在递归函数Backtrack中,在保证总花费不超过c的情况下:当i=n时,当前扩展结点是排列树的叶节点。
此时搜索到一个解,判断此时的最小重量是否小于当前最小重量,若小于则更新bestw, 并得到搜索路径bestx.当i〈n时,当前扩展结点位于排列树的第i—1层.当x[0:i]的花费小于给定最小花费时,算法进入排列树的第i层,否则将减去相应的子树。
算法用变量cc记录当前路径x[0:i]的费用。
3。
算法正确性证明通过几组实例证明合法的输入可以得到正确的输出.实例见附录第2部分。
4.算法复杂度分析时间复杂度是O(n2)5.参考文献[1] 王晓东编著,计算机算法设计与分析(第4版)。
北京:电子工业出版社,2012。
26。
附录(1)可执行代码如下:#include<iostream〉using namespace std;#define N 50class MinWmechine{int n; //部件个数int m;//供应商个数int COST; //题目中的Cint cw; //当前的重量int cc;//当前花费int bestw; //当前最小重量int bestx[N];int savex[N];int w[N][N];int c[N][N];public:MinWmechine();void machine_plan(int i);void prinout();};MinWmechine::MinWmechine(){cw=0; //当前的重量cc=0; //当前花费bestw=-1;//当前最小重量bestx[N];savex[N];cout<<”请输入部件个数:";cin〉〉n;cout〈〈”请输入供应商个数:"; cin>〉m;cout<<”请输入总价格不超过:"; cin>〉COST;for(int j=0;j<m;j++){for(int i=0;i〈n;i++)cout〈〈"请输入第"〈〈j+1〈<" 个供应商的第"〈〈i+1<〈”个部件的重量:”;cin>>w[i][j];cout〈〈”请输入第”〈<j+1〈<”个供应商的第”〈<i+1<<”个部件的价格:";cin〉>c[i][j];if(w[i][j]〈0 ||c[i][j]<0){cout〈<"重量或价钱不能为负数!\n";i=i—1;}}}}void MinWmechine::machine_plan(int i){if(i>=n){if(cw 〈bestw || bestw==—1){bestw=cw;for(int j=0;j〈n; j++) //把当前搜过的路径记下来savex[j]=bestx[j];return;}for(int j=0; j<m; j++)//依次递归尝试每个供应商{if(cc+c[i][j]〈COST){cc+=c[i][j];cw+=w[i][j];bestx[i]=j;machine_plan(i+1);bestx[i]=-1;cc-=c[i][j];cw—=w[i][j];}}}void MinWmechine::prinout(){int i,j,ccc=0;for(j=0;j〈m;j++){for(i=0;i〈n;i++){cout<〈"第”<<j+1〈<”供应商的第”<〈i+1〈〈”部件重量:”<〈w[i][j]〈〈" 价格:"<〈c[i][j]<<"\n”;}}for(j=0; j<n; j++){bestx[j]=-1;}machine_plan(0);cout<<”\n最小重量机器的重量是:"〈<bestw〈〈endl;for(int k=0;k〈n;k++){cout<<" 第"〈〈k+1〈〈" 部件来自供应商”〈<savex[k]+1<〈"\n”;ccc+=c[k][savex[k]];}cout〈〈"\n该机器的总价钱是: "<〈ccc<<endl;cout〈<endl;}int main(void){MinWmechine Y;Y。
机械机床分配问题

任务分配到机床摘要本文解决的是在不同加工要求下,机床加工过程中的任务分配问题,属于组合优化问题。
为解决此问题,我们运用数学中的约束规划与整数规划的混合方法[1] ,建立起最优化模型。
针对问题一:本文首先根据机床工作时间定义机床任务量均衡度,均衡度越小,各机床任务量越均衡。
由于不同产品加工任务量、可用机床不同,本文将整数规划作为主问题解决机器的分派问题,将约束规划作为子问题解决任务在机床上加工的排序问题。
然后确立两个目标函数:最短完成订单时间,最小均衡度。
最后根据确立的这两个目标建立起双目标最优化模型,运用lingo软件编程得到完成订单的最短时间为270小时,机床任务量均衡度为1.4%,各机床任务分配见5.3表二,各机床完成加工时间如下表:机床1机床2机床3机床4机床5机床6 230小时259小时231小时231小时267小时270小时针对问题二:本文在解决问题一的基础上,将机床的加工时间作为变量1,将产品在机床间的调度次数作为变量2,并以机床运行费用和调度费用确立的总生产费为目标函数,建立起单目标最优化模型,运用lingo软件编程得到最小总生产费用为202.75万元,各机床任务分配见6.3表四,各机床加工费用和调度总费用如下表:机床机床1 机床2 机床3 机床4 机床5 机床6 调度费用总费用费用(万)45.4 41.58 34.65 27.72 23 18.4 12 202.75 最后我们针对实际情况,对模型进行了改进,改进后的整数规划与约束规划模型使机床加工调度问题更接近实际,此时得出的分配方案更优。
关键字:约束规划整数规划车间作业调度一问题重述1.1问题背景在制造企业的中期或短期生产计划管理中,常常要考虑到如下的生产计划优化问题:在给定的外部需求和生产能力等限制条件下,按照一定的生产目标(生产总时间最小、生产总费用最小)编制未来若干个生产周期的最优生产计划。
1.2该工厂机床加工各种产品相关信息某工厂收到了5个客户提交的5种不同的加工任务订单,5个客户的任务订单量分别为 8,13,7,12,5。
优先队列最小重量机器设计问题

4.代ቤተ መጻሕፍቲ ባይዱ:
最小重量机器设计问题
1.问题描述:
设某机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设 是从供应商j处购得的部件i的重量, 是相应的价格。设计一个优先队列式分支限界法,给出总价格不超过d的最小重量机器设计。
2.算法设计
问题的解空间为一棵排列树,采用优先队列式分支限界法找出所给的最小重量机器设计。开始时,将排列树的根节点置为当前扩展结点。在初始扩展结点处还设有选定部件是哪个供应商提供的,故level=0,source=0,value=0,weight=0。MinLeaf记录满足条件的节点即供应商的选择。while完成对排列树内部结点的有序扩展。循环体内依次从活结点优先队列中取出具有最小重量的结点,依次为当前扩展结点。并且花费不超过d并加以扩展,队列为空时则结束循环。当fartherNode->level等于n时,此时扩展结点是叶节点,判断是否最优,若最优则记录节点。当fartherNode->level<n时,算法依次产生当前扩展结点的所有儿子节点。对于当前扩展结点的一个儿子结点,计算出当前的重量,当小于当前的最小重量时,将儿子结点插入到活结点优先队列中,而当不下于当前最小重量时,以当前这个结点为根的子树中不可能有比当前最小重量部件选择更好的解,故可将此结点舍去。若在一结点所计算的花费大于所给的最小花费,则剪去以此节点为根的子树。
《算法设计》课程报告--最小重量机器设计问题-新版.pdf

m个
不同的供应商处购得。高
wij 是从供应商 j 处购得的部件 i 的重量,
cij 是相应的价格。
试设计一个算法,给出总价格不超过
c 的最小重量机器设计。
编程任务: 对于给定的机器部件重量和机器部件价格,编程计算总价
格不超过 d 的最小重量机器设计。 数据输入:由文件 input.txt 给出输入数据。第一行有
-2-
课程名称:
学生姓名:
学生学号:
if(t>n){
if(cur_minWeight < minWeight){//
保存最优解和最优值
minWeight = cur_minWeight;
for(int r=1;r<=n;++r){
solution[r] = cur_solution[r];
}
}
}
else{
for(int i=1;i<=m;++i){
d -= c[t][i];
cur_solution[t] = i;
cur_minWeight += w[t][i];
if(d>=0) {
Backtrack(t+1,n,m,d);
}
cur_minWeight -= w[t][i];
//if(Constraint(t) && Bound(t)) Backtrack(t+1,n,m,d);
}
return 0;
}
分支定界法代码
#include <stdio.h>
#include <stdlib.h>
#include <list>
最小重量机器设计问题

问题描述
最小重量机器设计问题: 设某一机器由n个部件组成,每一种部 件可以从m个不同的供应商处购得。设wij 是从供应商j处购得的部件i的重量,cij是相 应的价格。 试设计一个算法,给出总价格不超过c 的最小重量机器设计。
算法设计:对于给定的机器部件重量和机 器部件价格,计算总价格不超过d的最小重 量机器设计。 数据输入:由文件input.txt给出输入数据。 第一行有3个正整数n,m和d。接下来的2n 行,每行n个数。前n行是c,后n行是w。 结果输出:将计算的最小重量及每个部件 的供应商输出到文件output.txt。
ห้องสมุดไป่ตู้
2. 每一个零件的最后一个商家已经被考虑过,返回 上一个零件的选择。 其中对于最后一个零件,一旦商家的零件型号被 选中,比较已经记录的最优总重量与该采购清单的总 重量,如果比最优总重量要小,更改最优采购清单及 最优总重量,不再进入下一个零件的选择。 对于第一个零件,当其所有商家都已被考虑后, 就终止。 这里使用i表示正在选择第i个零件,使用a[i]表示 第i个零件选择的商家,i++和i--表示递进或回溯,由 于最后判断终止条件时需要判断第一个零件选择到了 最后一个商家时,是不是从下层回溯回来的,如果是, 则终止,否则,则是第一个零件选择了最后一个商家, 而且将要进入下面的零件的选择,所以使用bool型变 量direction表示是否是回溯(false表示由下一层回溯)。
算法思想
本题的实质是在解析空间进行搜索,进行深度优先搜索, 但是为了节省空间与时间资源,使用数组以及条件判断来 模拟基于深度优先的回溯法。 对于搜索中的每一步,有如下情况: 1.不是最后一个零件还没有考虑完所有商家,选择每一 个零件的商家不是最后一个商家,只有两种情况,该商家 的零件型号符合要求(即包括该零件,已经选择的零件总 价格没有超过价格上限),则确定该零件选择该商家,并 进入下一个零件的选择,或者该商家的零件型号不符合要 求,跳过该商家,该零件开始选择下一个商家。
5.4 最小重量机器设计问题

5.4 最小重量机器设计问题算法设计思想:这是最优规划问题,采用回溯法求解。
用动态数组存放选购方案,通过递归函数进行零件的搜索和方案的剪枝,最终得到最小重量的机器零件选购方案。
递归函数void Search(int i, int s, int l, int *e)有4个参数:1.i是搜索的起点,初始从i=1(第一个零件)开始,满足条件i==n+1时表示找到一种选购方案,作为递归的结束条件;2.s是当前重量,也是规划目标。
题目要找最小重量的机器,因此设置一个min,每次找到一个选购方案时比较s,保留较小的。
另外,在搜索的过程中,判断条件s>min,一旦成立,说明已经不可能是最优解,即可进行剪枝。
3.l是当前价格,题目要求机器的总价格不超过d,因此l<d是规划的约束条件。
4.*e是当前选购方案,存储已经选出的零件。
当递归达到结束条件,且满足重量和价格要求时,e中存放了一种更优的选购方案,于是更新选购方案*plan。
整个程序搜索完成之后,*plan中存放的即使整体的最优选购方案。
该算法重点是控制递归过程的参数变化,递归的结束条件和优化剪枝方法。
另外,程序有一定的鲁棒性,对非法输入和文件错误进行了检测。
程序设计代码:/*头文件最小重量机器设计问题.h*/#ifndef KNAP_H#define KNAP_H#include <iostream>#include <fstream>using namespace std;class Machine //机器类{public:Machine(char *in, char *out); //构造函数~Machine(); //析构函数void Solve(); //输出结果到文件protected:void Search(int i, int s, int l, int *e); //从第i个部件开始递归搜索void Print(); //输出结果private:int n; //部件个数int m; //供应商个数int d; //价格上限int **w; //部件重量int **c; //部件价格int min; //最小重量int *plan; //选购的部件ofstream fout; //输出结果文件};#endif/*函数实现文件最小重量机器设计问题.cpp*/#include "最小重量机器设计问题.h"Machine::Machine(char *in, char *out) : fout(out){ifstream fin(in);if( !fin ){cerr << "文件" << in << "无法打开!" << endl;exit(1);}fin >> n >> m >> d; //初始化部件个数n,供应商数m,价格限制d w = new int*[n+1];for(int i = 1; i <= n; i++){w[i] = new int[m+1];for(int j = 1; j <= m; j++)fin >> w[i][j]; //初始化部件重量}c = new int*[n+1];for(int i = 1; i <= n; i++){c[i] = new int[n+1];for(int j = 1; j <= m; j++)fin >> c[i][j]; //初始化部件价格}fin.close();min = INT_MAX; //初始化最小重量plan = new int[n+1];for(int i = 1; i <= n; i++)plan[i] = 0; //初始化选购计划if( !fout ){cerr << "文件" << out << "无法打开!" << endl;exit(1);}}Machine::~Machine(){if(fout)fout.close();for(int i = 1; i <= n; i++){if(w[i])delete[] w[i];if(c[i])delete[] c[i];}if(w)delete[] w;if(c)delete[] c;}void Machine::Solve(){int *e;e = new int[n+1];for(int i = 1; i <= n; i++)e[i] = 0;Search(1, 0, 0, e); //第一个零件开始搜索,初始重量和价格是0 Print(); //输出函数}void Machine::Search(int i, int s, int l, int *e){if(i == n+1) //选购完毕{if(s < min && l <= d) //找到一个更优解{min = s; //更新重量最小值for(int i = 1; i <= n; i++)plan[i] = e[i]; //更新选购计划}return;}if(s > min) //重量超过min,剪枝return;for(int j = 1; j <= m; j++){e[i] = j;s += w[i][j]; //加上第i部件由j供应商提供的重量l += c[i][j]; //加上第i部件由j供应商提供的价格Search(i+1, s, l, e); //递归选购下一个部件s -= w[i][j];l -= c[i][j];}}void Machine::Print(){fout << min << endl;for(int i = 1; i <= n; i++)fout << plan[i] << ' ';}/*主函数文件test.cpp*/#include "最小重量机器设计问题.h"int main(){char *in = "input.txt"; //输入文件char *out = "output.txt"; //输出文件Machine machine(in, out); //文件初始化机器machine.Solve(); //回溯法求解return 0;}。
机床任务分配问题数学建模

任务分配到机床摘要本文解决的是机床生产调度的问题,目的是使产品加工路径的组合优化。
对于本文所研究的机床任务的合理调度问题,由于生产方式的不确定,我们根据A,B,C,D这4道工序是否有序进行了分类研究,并分情况得到了最优解或近似最优解,制定出了不同情况下的合理调度方案。
对于问题一:在工序无序的情况下,问题转化为一个指派问题,以完成任务耗时最长的那台机床的运行时间作为指标,以该指标最小作为目标函数,建立了一个0-1整数规划模型,用Lingo求解得最短加工时间为233h各机床加工时间的均衡度为3.8%。
在工序有序的情况下,问题一转化为一个柔性作业车间调度问题,此时生产调度的任务就是:确定产品的加工路径和每一工序的加工开始时间,并使产品通过系统的时间(Makespan)最小。
运用遗传算法建立模型,绘制出最佳调度的甘特图,并得到加工时间的近似最优解为250h,各机床加工时间均衡度为1.6%,均衡度很高;与无序情况所得最优解相比,其近似度为92.7%,具有较好的有效性。
对于问题二:在工序无序的情况下,该问题仍为一个指派问题,在加入调度费用与运行费用的条件下,我们利用理想点法将这两个指标的双目标问题转化为单目标规划模型来进行求解,建立了一个0-1整数规划模型,用Lingo求解得加工时间为510h,总费用为1784600元。
在工序有序的情况下,我们运用蚁群算法建立模型,经过选工序,计算加工工序k的机床的空闲时间段和加工序列,计算可选工序的EAPT和信息素的积累等过程,得到加工时间为441h,总费用为1799000元。
为了进一步分析该算法的有效性,我们还进行了实例规模较大的计算机仿真试验。
我们在模型的改进和推广里对模型四提出了一种评价方法,力求使一群算法的精度进一步提高,以实现更大规模的应用。
关键词:指派问题柔性调度理想点法遗传算法蚁群算法1.问题重述1.1问题背景车间生产调度是制造系统的基础,生产调度的优化方法是先进制造技术的核心技术。
-最小重量机器设计问题

-最小重量机器设计问题课题负责人名(学号):- 同组成员名单(角色):-指导教师:-评阅成绩:评阅意见:提交报告时间:xx年6 月17 日最小重量机器设计问题计算机科学与技术专业学生指导老师-[题目描述] 设某一机器由 n 个部件组成,每一种部件都可以从 m 个不同的供应商处购得。
高wij 是从供应商 j 处购得的部件 i 的重量,cij 是相应的价格。
试设计一个算法,给出总价格不超过 c 的最小重量机器设计。
编程任务:对于给定的机器部件重量和机器部件价格,编程计算总价格不超过 d 的最小重量机器设计。
数据输入:由文件 input、txt 给出输入数据。
第一行有3 个正整数 n,m 和 d。
接正业的2n 行,每行 n 个数。
前 n 行是 c,后 n 行是 w。
结果输出:将计算出的最小重量,以及每个部件的供应商输出到文件output、txt。
输入文件示例输出文件示例input、txt output、txt3344123131321222123321222[算法分析]采用回溯算法和分支定界法分别实现,对于回溯法,采用深度优先搜索对子集树进行剪枝,剪枝条件是当前的总费用不超过总费用;对于分支定界法,采用按照层次遍历对子集树进行剪枝,并将每层的结点按照重量由小到大进行排序,将相应下标保存在二维数组s中,以便构造最优解。
两种算法是时间复杂度都是O(m^n),空间复杂度均为O(nm),但由于分支定界法在已经排好序的序列中查找,因此查找到的第一个解即为最优解,理论上来说,时间效率会比回溯法高。
[程序实现]回溯法代码#include <iostream>#include<stdlib、h>#include <fstream>#include <vector>#include<stdio、h>#include <string、h>using namespace std;#define INF999999999#define MAXSIZE100+1intcur_solution[MAXSIZE];int solution[MAXSIZE];intw[MAXSIZE][MAXSIZE]; //weightint c[MAXSIZE][MAXSIZE];//costint minWeight; int cur_minWeight;void Backtrack(int t,int n,int m,int d){if(t>n){if(cur_minWeight < minWeight){//保存最优解和最优值minWeight =cur_minWeight;for(int r=1;r<=n;++r){solution[r] =cur_solution[r];}}}else{for(int i=1;i<=m;++i){d=w[t][i];//if(Constraint(t)&& Bound(t))Backtrack(t+1,n,m,d);d += c[t][i];}}return;}intmain(){int n,m,d;cout<<"Please input the input file path:"<<endl;charstrPath[63];while(scanf("%s",strPath)==1){ifstreamfin(strPath);cout<<"Please input the output filepath:"<<endl;cin>>strPath;ofstream fout(strPath);if(fin、good()&& fout、good()){minWeight = INF;cur_minWeight =0;fin>>n>>m>>d;intj,k;for(j=1;j<=n;++j){for(k=1;k<=m;++k){fin>>c[j][k];}}fo r(j=1;j<=n;++j){for(k=1;k<=m;++k){fin>>w[j][k];}}Backtrac k(1,n,m,d);fout<<minWeight<<endl;for(intr=1;r<=n;++r){fout<<solution[r]<<" ";}fout<<endl;fout、close();fin、close();}else{cout<<"Open fileerror!"<<endl;exit(0);}cout<<endl<<endl<<"Please input the input file path:"<<endl;}return 0;}分支定界法代码#include <stdio、h>#include <stdlib、h>#include<list>#include <iostream>using namespace std;#defineMAX_NODE256typedef struct _node{int weight,price;int level,th;struct _node *prev;}node;void qs(int *a,int*s,int b,int e)//快速排序{ int t,c=a[s[b]]; int l=b,r=e; while(l<r){ while(l<r&&a[s[r]]>=c)--r; t=s[r];s[r]=s[l];s[l]=t; while(l<r&&a[s[l]]<c)++l; t=s[r];s[r]=s[l];s[l]=t; }if(b<l)qs(a,s,b,l-1); if(l<e)qs(a,s,l+1,e);}intmain(){int *w=0,*p=0,n,m,c,i,j;int *minprice;intlevel,price,weight;list<node*> que;list<node*>::iteratorit;node *pnode;/* 读取文件 */FILE*pf;if((pf=fopen("input、txt","r"))!=0){fscanf(pf,"%d%d%d",&n,&m,&c);w=(int*)malloc(n*m*sizeof(int));//重量p=(int*)malloc(n*m*sizeof(int));//价格for(i=0;i<n;++i)for(j=0;j<m;++j)fscanf(pf,"%d",w+i*m+j);f or(i=0;i<n;++i)for(j=0;j<m;++j)fscanf(pf,"%d",p+i*m+j);fc lose(pf);}else{printf("no inputfile!!\n");getchar();exit(0);}/* 准备数据 */ints[n][m];//用来为每一种零件的质量排序,for(i=0;i<n;++i)for(j=0;j<m;++j)s[i][j]=j;minprice=(int*) malloc((n+1)*sizeof(int));//用来记录买了i个零件后,买完剩下的零件至少还要多少钱minprice[n]=0;//买了n个零件之后,不需要再买了for(i=0;i<n;++i){minprice[i]=p[i*m];for(j=1;j<m;++j)//找出买第i个零件的最低价格{minprice[i]=minprice[i]<p[i*m+j]?minprice[i]:p[i*m+j];}} for(i=n-2;i>=0;--i)//计算买剩下的零件至少要多少钱{minprice[i]=minprice[i+1]+minprice[i];}for(i=0;i<n;++i)/ /每种零件按重量排序,排序下标记录的s中,排序后w[i*m+s[i][j]],i相同时,对于变量j是递增的qs(w+i*m,s[i],0,m-1);/* 开始计算 */for(i=0;i<m;++i)//初始数据把第一种零件的所有情况放入活结点队列{pnode=new node;pnode->weight=w[s[0][i]];pnode->price=p[s[0][i]];if(pnode->price+minprice[2]<=c){pnode->th=i;pnode->level=1;pnode->prev =0;que、push_back(pnode);}else delete pnode;}while(!que、empty())//计算,直到得出结果或者队列为空{level =que、front()->level;price =que、front()->price;weight=que、front()->weight;if(level<n)for(i=0;i<m;++i)//如果队首不为叶子结点,扩展队首结点{pnode=new node;pnode->weight=weight+w[level*m+s[level][i]];pnode->price=price+p[level*m+s[level][i]];if(pnode->price+minprice[level+1]<=c)//剪枝,如果当前结点剩下的钱不够买全所有零件,则剪掉{pnode->th=s[level][i];pnode->level=level+1;pnode->prev =que、front();for(it=que、begin();it!=que、end();++it)//按重量递增构造优先队列if(pnode->weight<(*it)->weight)break;que、insert(it,pnode);if(level==n-1)break;//如果已经找到答案,退出循环}else delete pnode;}que、pop_front();if(i<m)break;//如果已经找到答案,退出循环}/* 输出答案 */if(pnode->level!=n){printf("can not find answer!!");getchar();exit(0);}pf=fopen("output、txt","w");if(pf){fprintf(pf,"%d\n",pnode->weight);int count=n,ans[n];while(pnode){ans[--count]=pnode->th;pnode=pnode->prev;}for(i=0;i<n;++i)fprintf(pf,"%d ",ans[i]);fputc('\n',pf);fclose(pf);}if(minprice)free(min price);if(w)free(w);if(p)free(p);return 0;}[运行结果]回溯法运行结果如下,分支定界法结果与下列一致,读者可以自行运行比对参考文献[1] 王晓东、计算机算法设计与分析、--3版、--北京:电子工业出版社xx、5。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、算法实现题5-3 最小重量机器设计问题
设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。
设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格,给出总价格不超过d的最小重量机器设计。
1、解题说明
这是一个最优规划问题,采用本章回溯法来求解。
解空间是一个子集树,因此通过递归函数对解空间进行深度优先搜索,只要在当前结点,只要满足限定条件和限界条件,则递归下一层,否则就尝试下一个供应商。
Backtrack(1)实现对整个解空间的回溯搜索,Backtrack(i)搜索解空间中第i层子树。
类Machine的数据成员记录界空间中结点信息。
在算法Backtrack中,当i>n的时候,算法搜索至叶节点,得到一个新的可行解,与当前最优解进行比较,并更新最优值。
当i<=n的时候,当前扩展结点是解空间中的内部结点。
该结点有m个子节点。
若满足当前总费用小于最大总费用,并且当前总重量小于最小总重量,那么以深度优先的方式递归地对可行子树进行搜索,或剪去不可行子树。
2、程序代码
#include<iostream>
#include<fstream>
using namespace std;
class Machine{ //机器类
public:
Machine(){ //构造函数
cw=cc=0;
minw=1000;
ifstream in("input.txt"); //从文件输入
in>>n>>m>>d;
bestprovider=new int[m+1]; //初始化最优供应商和供应商数组
provider=new int[m+1];
c=new double*[n+1]; //创建部件价格二维数组
for(i=1;i<=n;i++)
c[i]=new double[m+1];
for(i=1;i<=n;i++) //从文件读入价格
for(int j=1;j<=m;j++)
in>>c[i][j];
w=new double*[n+1]; //创建部件重量二维数组
for(i=1;i<=n;i++)
w[i]=new double[m+1];
for(i=1;i<=n;i++) //从文件读入重量
for(int j=1;j<=m;j++)
in>>w[i][j];
}
void Backtrack(int i){
if(i>n){ //已得到一个可行解
if(cw<minw){ //更新最小重量
minw=cw;
for(int j=1;j<=m;j++)
bestprovider[j]=provider[j];
}
return;
}
for(int j=1;j<=m;j++)
{
provider[i]=j;
//考虑第j个供应商
cc+=c[i][j];
cw+=w[i][j];
//满足限定条件并且满足限界条件,则递归下一层if(cc<=d&&cw<minw)
Backtrack(i+1);
//考虑下一个供应商
cc-=c[i][j];
cw-=w[i][j];
}
}
void Output(){ //输出到文件
ofstream out("output.txt");
cout<<minw<<endl;
out<<minw<<endl;
for(int k=1;k<=m;k++){
out<<bestprovider[k]<<' ';
cout<<bestprovider[k]<<' ';
}
out<<endl;
cout<<endl;
}
private:
int n,m,d,i; //n为部件个数,m为供应商个数,d为总价格上届,i为层数
double **w; //部件重量数组
double **c; //部件价格数组
double cw,cc,minw; //cw为当前重量,cc为当前价格,minw为最小重量
int *provider; //供应商数组
int *bestprovider; //最优供应商数组
};
int main(){
Machine mach;
mach.Backtrack(1);
mach.Output();
return 0;
}
3、运行截图
1)程序所在文件夹有input.txt,运行完成后产生了output.txt
2)输入文件input.txt
第一行分别是部件数量n,供应商数量m,和最大费用d;
紧接着输入一个n行m列的部件价格数组和一个n行m列的部件重量数组。
3)运行程序后,打开ouput.txt,输出结果如下:
Dos界面运行如下:
二、算法实现题5-13 工作分配问题
设有n件工作分配给n个人。
将工作i分配给第j个人所需的费用为cij 。
试设计一个算法,为每一个人都分配1 件不同的工作,并使总费用达到最小。
设计一个算法,对于给定的工作费用,计算最佳工作分配方案,使总费用达到最小。
1、解题说明
工作分配问题的解空间是一个排列树。
按照回溯法搜索排列数的算法框架。
相应的排列树由work[1:n]的所有排列给出。
在递归算法Backtrack中,当i>n的时候,算法搜索至叶节点,得到新的排列方案。
若当前总费用小于最小总费用,则更新最小总费用的值。
并返回。
当i<=n的时候,当前扩展结点位于排列树中,此时算法判断当前总费用是否小于最小总费用,若小于,则以深度优先的方式递归地对相应子树进行搜索。
否则剪去相应子树。
2、程序代码
#include<iostream>
#include<fstream>
using namespace std;
class Work{ //工作类
public:
Work(){ //构造函数
cc=0; //当前总费用赋初值为0
minc=10000; //最小费用赋初值为10000
ifstream in("input.txt"); //从文件读入n
in>>n;
work=new int[n+1]; //初始化工作数组
for(i=1;i<=n;i++)
{
work[i]=i;
}
c=new int*[n+1]; //创建费用二维数组
for(i=1;i<=n;i++)
c[i]=new int[n+1];
for(i=1;i<=n;i++){ //从文件读入二维数组for(int j=1;j<=n;j++)
{
in>>c[i][j];
cout<<c[i][j]<<" ";
}
cout<<endl;
}
}
void Backtrack(int i){
if(i>n){ //已得到一个可行解
if(cc<minc) //更新最小费用
minc=cc;
return;
}
for(int j=i;j<=n;j++)
{
if(cc<minc){ //搜索子树
swap(work[i],work[j]);
cc+=c[i][work[i]];
Backtrack(i+1);
cc-=c[i][work[i]];
swap(work[j],work[i]);
}
}
}
void Output(){
ofstream out("output.txt");
cout<<minc<<endl;
out<<minc<<endl;
}
public:
int n,i,j;
int **c;
int *work;
int cc,minc;
void swap(int &a,int &b){
int temp=a;
a=b;
b=temp;
}
};
int main(){
Work wk;
wk.Backtrack(1);
wk.Output();
return 0;
}
3、运行截图
1)程序所在文件夹有input.txt,运行完成后产生了output.txt
2)输入文件input.txt
第一行为工作数量n;接下来是n行n列的二维数组,表示每个工作分配给每个人的对应工作费用。
3)运行程序后,打开ouput.txt,输出结果如下:
dos界面运行如下:。