《算法设计》课程报告最小重量机器设计问题.docx
《《算法设计》课程报告最小重量机器设计问题.docx》由会员分享,可在线阅读,更多相关《《算法设计》课程报告最小重量机器设计问题.docx(10页珍藏版)》请在冰豆网上搜索。
《算法设计》课程报告最小重量机器设计问题
《算法设计》课程报告
课题名称:
算法设计
课题负责人名(学号):
---
同组成员名单(角色):
---
指导教师:
---
评阅成绩:
评阅意见:
提交报告时间:
2014年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.txtoutput.txt
3344
123131
321
222
123
321
222
[算法分析]
采用回溯算法和分支定界法分别实现,对于回溯法,采用深度优先搜索对子集树进行剪枝,剪枝条件是当前的总费用不超过总费用;对于分支定界法,采用按照层次遍历对子集树进行剪枝,并将每层的结点按照重量由小到大进行排序,将相应下标保存在二维数组s中,以便构造最优解。
两种算法是时间复杂度都是O(m^n),空间复杂度均为O(nm),但由于分支定界法在已经排好序的序列中查找,因此查找到的第一个解即为最优解,理论上来说,时间效率会比回溯法高。
[程序实现]
回溯法代码
#include
#include
#include
#include
#include
#include
usingnamespacestd;
#defineINF999999999
#defineMAXSIZE100+1
intcur_solution[MAXSIZE];
intsolution[MAXSIZE];
intw[MAXSIZE][MAXSIZE];//weight
intc[MAXSIZE][MAXSIZE];//cost
intminWeight;
intcur_minWeight;
voidBacktrack(intt,intn,intm,intd){
if(t>n){
if(cur_minWeightminWeight=cur_minWeight;
for(intr=1;r<=n;++r){
solution[r]=cur_solution[r];
}
}
}
else{
for(inti=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);
d+=c[t][i];
}
}
return;
}
intmain(){
intn,m,d;
cout<<"Pleaseinputtheinputfilepath:
"<charstrPath[63];
while(scanf("%s",strPath)==1){
ifstreamfin(strPath);
cout<<"Pleaseinputtheoutputfilepath:
"<cin>>strPath;
ofstreamfout(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];
}
}
for(j=1;j<=n;++j){
for(k=1;k<=m;++k){
fin>>w[j][k];
}
}
Backtrack(1,n,m,d);
fout<for(intr=1;r<=n;++r){
fout<}
fout<fout.close();
fin.close();
}
else{
cout<<"Openfileerror!
"<exit(0);
}
cout<"<}
return0;
}
分支定界法代码
#include
#include
#include
#include
usingnamespacestd;
#defineMAX_NODE256
typedefstruct_node
{
intweight,price;
intlevel,th;
struct_node*prev;
}node;
voidqs(int*a,int*s,intb,inte)//快速排序
{
intt,c=a[s[b]];
intl=b,r=e;
while(l{
while(l=c)--r;
t=s[r];s[r]=s[l];s[l]=t;
while(lt=s[r];s[r]=s[l];s[l]=t;
}
if(bif(l}
intmain()
{
int*w=0,*p=0,n,m,c,i,j;
int*minprice;
intlevel,price,weight;
listque;
list:
:
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;ifor(j=0;jfscanf(pf,"%d",w+i*m+j);
for(i=0;ifor(j=0;jfscanf(pf,"%d",p+i*m+j);
fclose(pf);
}
else
{
printf("noinputfile!
!
\n");
getchar();
exit(0);
}
/*准备数据*/
ints[n][m];//用来为每一种零件的质量排序,
for(i=0;ifor(j=0;js[i][j]=j;
minprice=(int*)malloc((n+1)*sizeof(int));//用来记录买了i个零件后,买完剩下的零件至少还要多少钱
minprice[n]=0;//买了n个零件之后,不需要再买了
for(i=0;i{
minprice[i]=p[i*m];
for(j=1;j{
minprice[i]=minprice[i]
minprice[i]:
p[i*m+j];
}
}
for(i=n-2;i>=0;--i)//计算买剩下的零件至少要多少钱
{
minprice[i]=minprice[i+1]+minprice[i];
}
for(i=0;iqs(w+i*m,s[i],0,m-1);
/*开始计算*/
for(i=0;i{
pnode=newnode;
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);
}
elsedeletepnode;
}
while(!
que.empty())//计算,直到得出结果或者队列为空
{
level=que.front()->level;
price=que.front()->price;
weight=que.front()->weight;
if(level{
pnode=newnode;
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;//如果已经找到答案,退出循环
}
elsedeletepnode;
}
que.pop_front();
if(i}
/*输出答案*/
if(pnode->level!
=n)
{
printf("cannotfindanswer!
!
");
getchar();
exit(0);
}
pf=fopen("output.txt","w");
if(pf)
{
fprintf(pf,"%d\n",pnode->weight);
intcount=n,ans[n];
while(pnode)
{
ans[--count]=pnode->th;
pnode=pnode->prev;
}
for(i=0;ifprintf(pf,"%d",ans[i]);
fputc('\n',pf);
fclose(pf);
}
if(minprice)free(minprice);
if(w)free(w);
if(p)free(p);
return0;
}
[运行结果]
回溯法运行结果如下,分支定界法结果与下列一致,读者可以自行运行比对
参考文献
[1]王晓东.计算机算法设计与分析.--3版.--北京:
电子工业出版社2007.5
[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!
]