01背包问题实验报告Word文档下载推荐.docx
- 文档编号:21271223
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:11
- 大小:61.62KB
01背包问题实验报告Word文档下载推荐.docx
《01背包问题实验报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《01背包问题实验报告Word文档下载推荐.docx(11页珍藏版)》请在冰豆网上搜索。
1.由0-1背包问题的最优子结构性质~建立计算m[i][j]的递归式如下:
j,wmax{m[i,1,j],m[i,1,j,w],v[i]},iim(i,j),,0,j,wm[i,1,j]i,
2.查找装入背包物品的函数:
从数组的最右下角开始寻找~如若m[i][weight]!
=
m[i-1][weight]~则该第i个物品就在背包中~将其从最大价值量中去掉~然后再接着寻找下一个在背包中的物品~直至i=0。
关键数据结构:
一个二维数组~两个一维数组~两个整型变量
intm[N+1][M+1]={0};
//用于存储当前最好的价值量
intnumber,weight;
//number表示物品的种类,weight表示背包重量的最大值
intw[N]={0},v[N]={0};
//分别表示物品的重量和价值
函数摻块:
Main函数调用其余两个个函数完成算法:
voidknapsack(intnumber,intweight,int*w,int*v,intm[][M+1]);
//整理背包函数,找出最大价值
voidfindobject(intnumber,intweight,int*w,int*v,intm[][M+1]);
//找出所有在背包里的物品的函数
五(最终算法设计:
算法:
1.voidknapsack(intnumber,intweight,int*w,int*v,intm[][M+1]){//数组m[][],其横坐标row表示物品是第几个,纵坐标col表示当前背包中物品的重量从1到weight
introw,col;
for(row=1;
row<
=number;
row++)
for(col=1;
col<
=weight;
col++)
{
if(col>
=w[row])//当背包重量大于第row个物品的重量时,再继续进行判断
-w[row]]+v[row]>
m[row-1][col])if(m[row-1][col
m[row][col]=m[row-1][col-w[row]]+v[row];
else
1][col];
//判断加入该第row个物品m[row][col]=m[row-
是否会增大价值量,若增大则加入,否则不加
}
m[row][col]=m[row-1][col];
//如果背包重量小于w[row],则不加入任何物品,价值量不变
printf("
Themostvalueoftheknapsackis:
%d.\n"
m[number][weight]);
//输出最大价值量
2.voidfindobject(intnumber,intweight,int*w,int*v,intm[][M+1]){
inti;
intx[N]={0};
for(i=number;
i>
0;
i--)//从数组的最右下角开始找寻,直到找到最开始的m[0][]
if(m[i][weight]!
=m[i-1][weight])
x[i]=1;
weight=weight-w[i];
//将找到的第i个物品从背包的重量中去掉
%dthobjectischosen.weight:
%d,value:
%d\n"
i,w[i],v[i]);
//输出找到的物品的信息
六(运行结果:
当输入的数据不符合要求时:
七(分析时间复杂度:
n为物品总数~c为重量限制背包容量,
从m(i~j)的递归式容易看出~算法需要O(nc)计算时间。
当背
n包容量c很大时~算法需要的计算时间较多。
例如~当c>
2时~算法
n需要Ω(n2)计算时间
八(改进算法:
算法思路:
1.由m(i,j)的递归式容易证明~在一般情况下~对每一个确定的i(1?
i?
n)~函数m(i,j)是关于变量j的阶梯状单调不减函数。
跳跃点是这一类函数的描述特征。
在一般情况下~函数m(i,j)由其全部跳跃点唯一确定。
如图所示。
对每一个确定的i(1?
n)~用一个表p[i]存储其全部跳跃点。
初始时p[0]={(0~0)}~然后依次计算p[1],p[2]….p[n]
先将p[i]中可能包含的所有数对找出~然后再对其进行筛选~将不符合背包容量限制的~不符合最大价值量的数对删除~构成最终的p[i]跳跃点。
2.找背包中所装物品的方法和最初的算法类似~从最后装入的物品开始找起~若max与q[i].value[q[i].total-1]相等并且max不与q[i-1].value[q[i-1].total-1]相等~则说明第i个物品在背包中~输出相应的信息。
直至max=0。
数据类型:
structobject
intwei[N*2];
intvalue[N*2];
inttotal;
}p[20],q[20];
//表示跳跃点集合的数据结构
intnumber,weight,max;
//number表示物品的种类,weight表示背包重量的最大值,max表示装入背包最大的价值
九(最终算法
1.voidknapsack(intnumber,intweight,int*w,int*v)
{//数组m[][],其横坐标row表示物品是第几个,纵坐标col表示当前背包中物品的重量从1到weight
inti,j,k,num;
//i控制新的数据结构q的下标,j,k控制元素的比较,num控制结构q中各个数组元素的下标
intmax,all;
//max表示最大价值
p[0].wei[0]=0;
//将p[0],q[0]初始化为只含(0,0)的数据结构
p[0].value[0]=0;
p[0].total=1;
q[0].wei[0]=0;
q[0].value[0]=0;
q[0].total=1;
for(i=1;
i<
i++)
p[i].total=q[i-1].total;
for(j=0;
j<
q[i-1].total;
j++)
p[i].wei[j]=q[i-1].wei[j];
p[i].value[j]=q[i-1].value[j];
}//将上个跳跃点的所有数对先复制下来
for(k=0;
k<
k++)
if(q[i-1].wei[k]+w[i]<
=weight)
p[i].wei[j]=q[i-1].wei[k]+w[i];
p[i].value[j]=q[i-1].value[k]+v[i];
p[i].total++;
j++;
}//计算加入新的物品后的未超出限制重量的数对
//以上是计算每个跳跃点q[i]所含数对的个数并对其赋值
//之后是对q[i]目前的所有数对进行合并并删除,将其有序化
all=p[i].total;
for(num=0,j=0,k=p[i-1].total;
p[i-1].total&
&
k<
all;
)
if(p[i].wei[j]<
p[i].wei[k])//总重量小的放在前面
if(p[i].value[j]<
=p[i].value[k])
q[i].wei[num]=p[i].wei[j];
q[i].value[num]=p[i].value[j];
num++;
}//总重量小并且价值小时,将其先放入q[i]中,num++
{
k++;
p[i].total--;
}//总重量小单价值大时,将另一个删除,跳跃点所含数对数减1,再继续进行比较
elseif(p[i].wei[j]==p[i].wei[k])
p[i].value[k])
q[i].wei[num]=p[i].wei[k];
q[i].value[num]=p[i].value[k];
//k价值大
//j价值大
//总重量相等时,必定有个价值大的,将其写入p[i],另一个删除
else//j的总重量比k大时
if(p[i].value[j]>
}//j的价值也比k大时,将k写入p[i],num++
}//价值小的总重量大时,将其删除,再继续进行比较
q[i].total=p[i].total;
//下面将对剩余的没有排序的最后数对加入p[i]
while(j<
q[i-1].total)
if(p[i].value[j]<
q[i].value[num-1])
q[i].total--;
}//若j的价值比之前的最大的小。
则将其删除
else
}//否则,将其加在之前填好p[i]的末尾
while(k<
all)
if(p[i].value[k]<
}//若k的价值比之前的最大的小。
max=q[i-1].value[q[i-1].total-1];
max);
2.voidfindobject(intnumber,int*w,int*v){
inti,j;
//控制循环
intmaxw,maxv;
maxw=q[number].wei[q[number].total-1];
maxv=q[number].value[q[number].total-1];
=0;
i--)
for(j=q[i-1].total-1;
j>
j--)
if((maxw-w[i])==q[i-1].wei[j]&
(maxv-v[i])==
q[i-1].value[j])
{//当某个物品所属行的最大价值量与之前的物品的不同时,该物品
即为装入包中物品
%dthobjectischosen.
weight:
maxw=maxw-w[i];
maxv=maxv-v[i];
//将去掉该物品后的最大价值量修改
break;
if(maxw==q[i-1].wei[j]&
maxv==q[i-1].value[j])
十(运行结果
十一.分析时间复杂度
上述算法的主要计算量在于计算跳跃点集p[i](1?
n)。
由于q[i+1]=p[i+1],(w~v)~故计算q[i+1]需要O(|p[i+1]|)计算时间。
ii
合并p[i+1]和q[i+1]并清除受控跳跃点也需要O(|p[i+1]|)计算时间。
从跳跃点集p[i]的定义可以看出~p[i]中的跳跃点相应于x,…,x的0/1赋值。
in
n-i+1因此~p[i]中跳跃点个数不超过2。
由此可见~算法计算跳跃
nn,,,,,nin,,O|p[i,1]|,O2,O2,,,,点集p[i]所花费的计算时间为,,,2,2ii,,,,
n从而~改进后算法的计算时间复杂性为O
(2)。
当所给物品的重量w(1?
n)是整数时~|p[i]|?
c+1~(1?
在这种情况下~改进后i
n算法的计算时间复杂性为O(min{nc,2})。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 01 背包 问题 实验 报告