01背包实验报告

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

算法设计与分析实验报告实验二 0-1背包

院系:

班级:

学号:

姓名:

任课教师:

成绩:

年月

实验二 0-1背包

一. 实验内容

分别用编程实现动态规划算法和贪心法求0-1背包问题的最优解,分析比较两种算法的时间复杂度并验证分析结果

二.实验目的

1、掌握动态规划算法和贪心法解决问题的一般步骤,学会使用动态规划和贪心法解决实际问题;

2、理解动态规划算法和贪心法的异同及各自的适用范围。

三. 算法描述

1、动态规划法

01背包问题的状态转换公式为: (1) V(i, 0)= V(0, j)=0

(2) 公式表明:把前面i 个物品装入容量为0的背包和把0个物品装入容量为j 的背包,得到的价值均为0。如果第i 个物品的重量大于背包的容量,则装入前i 个物品得到的最大价值和装入前i -1个物品得到的最大价值是相同的,即物品i 不能装入背包;如果第i 个物品的重量小于背包的容量,则会有以下两种情况:

(1)如果把第i 个物品装入背包,则背包中物品的价值等于把前i -1个物品装入容量为j -wi 的背包中的价值加上第i 个物品的价值vi ;

(2)如果第i 个物品没有装入背包,则背包中物品的价值就等于把前i -1个物品装入容量为j 的背包中所取得的价值。显然,取二者中价值较大者作为把前i 个物品装入容量为j 的背包中的最优解。

2、贪心法

背包问题至少有三种看似合理的贪心策略:

(1)选择重量最轻的物品,因为这可以装入尽可能多的物品,从而增加背包的总价值。但是,虽然每一步选择使背包的容量消耗得慢了,但背包的价值却没能保证迅速增长,从而不能保证目标函数达到最大。

(2)选择价值最大的物品,因为这可以尽可能快地增加背包的总价值。但是,虽然每一步选择获得了背包价值的极大增长,但背包容量却可能消耗得太快,使得装入背包的物品个数减少,从而不能保证目标函数达到最大。

(3)选择单位重量价值最大的物品,在背包价值增长和背包容量消耗两者

⎩⎨

⎧>+---<-=i i i i w

j v w j i V j i V w j j i V j i V }),1(),,1(max{)

,1(),(

之间寻找平衡,即利用性价比求的目标函数最大。

应用第三种贪心策略,每次从物品集合中选择单位重量价值最大的物品,如果其重量小于背包容量,就可以把它装入,并将背包容量减去该物品的重量,然后我们就面临了一个最优子问题——它同样是背包问题,只不过背包容量减少了,物品集合减少了。因此背包问题具有最优子结构性质。

四.算法实现

(一)动态规划法

1.数据结构及函数说明

int max(int i,int j);//比较并返回两个数中的较大值

int KnapSack (int w[],int v[],int x[],int n,int c);//求解背包取得的最大值

2.源程序代码

#include

#include "stdio.h"

#include

#include

using namespace std;

//比较并返回两个数中的较大值

int max(int i,int j)

{

if(i

return j;

else

return i;

}

//求解背包取得的最大值

int KnapSack (int w[],int v[],int x[],int n,int c)

{

int i,j,V[105][1005]={0};

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

V[i][j]=V[i-1][j];

else

V[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+v[i]);

}

}

for(j=c,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];

}

int main()

{

int c,n,w[105],v[105],x[105],max;//x[]记录物品的选择情况int i,j,k=10;

FILE *fp,*fp1;//定义文件指针

if((fp=fopen("input.txt","r"))==NULL)//如果文件名不存在{cout<<"无法找到文件";}

while(k--){

clock_t start,finish;

double totaltime;

start=clock();

cout<<"请输入背包的容量:";

fscanf(fp,"%d",&c);

cout << c <<"\n";

cout<<"请输入物品的个数:";

fscanf(fp,"%d",&n);

cout << n <<"\n";

相关文档
最新文档