《算法设计》课程报告最小重量机器设计问题Word格式文档下载.docx
《《算法设计》课程报告最小重量机器设计问题Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《《算法设计》课程报告最小重量机器设计问题Word格式文档下载.docx(10页珍藏版)》请在冰豆网上搜索。
输入文件示例输出文件示例
input.txtoutput.txt
3344
123131
321
222
123
[算法分析]
采用回溯算法和分支定界法分别实现,对于回溯法,采用深度优先搜索对子集树进行剪枝,剪枝条件是当前的总费用不超过总费用;
对于分支定界法,采用按照层次遍历对子集树进行剪枝,并将每层的结点按照重量由小到大进行排序,将相应下标保存在二维数组s中,以便构造最优解。
两种算法是时间复杂度都是O(m^n),空间复杂度均为O(nm),但由于分支定界法在已经排好序的序列中查找,因此查找到的第一个解即为最优解,理论上来说,时间效率会比回溯法高。
[程序实现]
回溯法代码
#include<
iostream>
stdlib.h>
fstream>
vector>
stdio.h>
string.h>
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_minWeight<
minWeight){//保存最优解和最优值
minWeight=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:
endl;
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<
++j){
for(k=1;
k<
++k){
fin>
c[j][k];
}
w[j][k];
Backtrack(1,n,m,d);
fout<
minWeight<
fout<
solution[r]<
"
;
fout.close();
fin.close();
else{
cout<
Openfileerror!
exit(0);
endl<
return0;
分支定界法代码
list>
#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<
r)
{
r&
a[s[r]]>
=c)--r;
t=s[r];
s[r]=s[l];
s[l]=t;
a[s[l]]<
c)++l;
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;
:
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;
n;
++i)
for(j=0;
m;
++j)
fscanf(pf,"
%d"
w+i*m+j);
p+i*m+j);
fclose(pf);
else
printf("
noinputfile!
!
\n"
);
getchar();
exit(0);
/*准备数据*/
ints[n][m];
//用来为每一种零件的质量排序,
for(i=0;
for(j=0;
s[i][j]=j;
minprice=(int*)malloc((n+1)*sizeof(int));
//用来记录买了i个零件后,买完剩下的零件至少还要多少钱
minprice[n]=0;
//买了n个零件之后,不需要再买了
minprice[i]=p[i*m];
for(j=1;
++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];
++i)//每种零件按重量排序,排序下标记录的s中,排序后w[i*m+s[i][j]],i相同时,对于变量j是递增的
qs(w+i*m,s[i],0,m-1);
/*开始计算*/
++i)//初始数据把第一种零件的所有情况放入活结点队列
pnode=newnode;
pnode->
weight=w[s[0][i]];
price=p[s[0][i]];
if(pnode->
price+minprice[2]<
=c)
{
pnode->
th=i;
level=1;
prev=0;
que.push_back(pnode);
elsedeletepnode;
while(!
que.empty())//计算,直到得出结果或者队列为空
level=que.front()->
level;
price=que.front()->
price;
weight=que.front()->
weight;
if(level<
n)for(i=0;
++i)//如果队首不为叶子结点,扩展队首结点
pnode=newnode;
weight=weight+w[level*m+s[level][i]];
price=price+p[level*m+s[level][i]];
if(pnode->
price+minprice[level+1]<
=c)//剪枝,如果当前结点剩下的钱不够买全所有零件,则剪掉
{
pnode->
th=s[level][i];
level=level+1;
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<
m)break;
/*输出答案*/
if(pnode->
level!
=n)
cannotfindanswer!
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;
fprintf(pf,"
%d"
ans[i]);
fputc('
\n'
pf);
if(minprice)free(minprice);
if(w)free(w);
if(p)free(p);
[运行结果]
回溯法运行结果如下,分支定界法结果与下列一致,读者可以自行运行比对
参考文献
[1]王晓东.计算机算法设计与分析.--3版.--北京:
电子工业出版社2007.5