算法设计与分析报告课程设计报告材料
- 格式:doc
- 大小:86.15 KB
- 文档页数:8
湖南理工学院课程论文
论文题目 0-1背包问题的设计与实现
课程名称数据结构与算法设计
姓名学号
专业班级年级 2014级
学院计算机学院日期 2015年6月25日
课程论文评价标准
目录
1.问题描述 (3)
2.算法设计分析 (3)
3.程序编码与调试分析 (5)
4.测试结果 (7)
5.自学知识 (7)
6.课程设计心得体会 (8)
7.参考文献 (8)
1.问题描述
给定n种物品和一个背包,物品i的重量是w i,其价值为v i,背包容量为C。
在选择装入背包的物品时,对每种物品i只有两种选择:装入背包或不装入背包,即不能将物品i装入背包多次,也不能只装入物品i的一部分。
问:如何选择装入背包的物品,使得装入背包中物品的总价值最大?
2.算法设计与分析
算法分析
在0-1背包问题中,物体被装入一个背包,或者不被装入背包,设x i表示物品i装入背包的情况,则当x i=0时,表示物品i没有被装入背包,x i=1时,表示物品i被装入背包。
假设有五个物品,其重量分别是{2,2,6,5,4},价值分别是{6,3,5,4,6},背包的容量为10。
根据动态规划函数,用一个(n+1)×(C+1)的二维表V,V[i][j]表示把前i个物品装入容量为j的背包中获得的最大价值。
按下述方法来划分阶段:第一阶段,只装入前1个物品,确定在各种情况下的背包能够得到的最大价值;第二阶段,只装入前2个物品,确定在各种情况下的背包能够得到的最大价值;依此类推,直到第n个阶段。
最后,V(n,C)便是在容量为C的背包中装入n个物品时取得的最大价值。
为了确定装入背包的具体物品,从V(n,C)的值向前推,如果V(n,C)>V(n-1, C),表明第n个物品被装入背包,前n-1个物品被装入容量为C-w
的背包中;
n
否则,第n个物品没有被装入背包,前n-1个物品被装入容量为C的背包中。
依此类推,直到确定第1个物品是否被装入背包中为止。
算法设计
设n个物品的重量存储在数组w[n]中,价值存储在数组v[n]中,背包容量为C,数组V [n+1][C+1]存放迭代结果,其中V[i][j]表示前i个物品装入容量为j的背包中获得的最大价值,数组x[n]存储装入背包的物品,动态规划法求解0/1背包问题的算法如下:
int KnapSack(int n, int w[ ], int v[ ])
{
for (i=0; i<=n; i++) //初始化第0列
V[i][0]=0;
for (j=0; j<=C; j++) //初始化第0行
V[0][j]=0;
for (i=1; i<=n; i++) //计算第i行,进行第i次迭代
for (j=1; j<=C; j++)
if (j<w[i]) V[i][j]=V[i-1][j];
else V[i][j]=max(V[i-1][j], V[i-1][j-w[i]]+v[i]); j=C; //求装入背包的物品
for (i=n; i>0; i--){
if (V[i][j]>V[i-1][j]) {
x[i]=1;
j=j-w[i];
}
else x[i]=0;
}
return V[n][C]; //返回背包取得的最大价值
}
3.程序编码与调试分析
程序编码
#include<stdio.h>
#include<math.h>
int max(int x,int y){
if(x>=y)
return x;
else
return y;
}
int KnapSack(int n,int C,int *w,int *v,int V[][11]) { int i,j,x[i];
for (i=0;i<=n;i++) //初始化第0列
V[i][0]=0;
for (j=0;j<=C;j++) //初始化第0行
V[0][j]=0;
for (i=1;i<=n;i++) //计算第i行,进行第i次迭代
for (j=1;j<=C;j++)
if (j<w[i])
V[i][j]=V[i-1][j];
else
V[i][j]=max(V[i-1][j], V[i-1][j-w[i]]+v[i]);
j=C; //求装入背包的物品
for (i=n; i>0; i--){
if (V[i][j]>V[i-1][j]) {
x[i]=1;
j=j-w[i];
}
else x[i]=0;
}
for(i=0;i<=n;i++)
{for(j=0;j<=C;j++)
printf("%3d ",V[i][j]);
printf("\n");
}
printf("背包取得的最大价值:");
printf("%d",V[n][C]); //返回背包取得的最大价值
}
int main(){
int n=5,C=10,i;
int V[6][11];
int w[6],v[6];
for(i=1;i<6;i++)
scanf("%d",&w[i]);
for(i=1;i<6;i++)
scanf("%d",&v[i]);
KnapSack(5,10,w,v,V);
}
调试分析
以上0-1背包问题的代码的时间复杂度为O(nc).(n表示物品的总数,c为重量限制背包容量),当背包容量c很大时,算法需要的计算时间比较多。
动态规划依赖于上一个或者上一行的解,所以我常在输出子序列的时候出现问题,这源自于对动态规划的知识不是很了解。
4.测试结果
5.自学知识
在这个程序设计中,涉及了动态规划,动态规划是解决多阶段决策问题常用的最优化理论,其基本思想是沿着决策的阶段划分自问题,决策的阶段可以随时间划分,也可以随着问题的转换状态划分。
设计动态规划算法,通常可按照以下几个步骤进行:
(1)找出最优解的性质,并刻画其结构特征。
(2)递归地定义最优解的值。
(3)以自底而上的方式计算出最优值。
(4)根据计算最优值时得到的信息,构造一个最优解。
6.课程设计心得体会
动态规划依赖于上一个或上一行的解,这次实验总是在输出子序列的时候出现问题,本来动态规划的知识没有学好,正好在最后的课程设计选0-1背包问题作为实验对象,完完整整的通过这次设计对0-1背包问题和动态规划都有了很深刻的了解,这有助于以后我们在实际问题中解决一些复杂性较大的问题,提高程序的运行效率。
7.参考文献
[1] 谭浩强等. 《C语言程序社会》,清华大学出版社,2013.
[2] 王晓华等. 《算法的乐趣》,人民邮电出版社, 2015.。