01背包动态规划回溯和背包贪心实验报告.docx

上传人:b****3 文档编号:26716632 上传时间:2023-06-22 格式:DOCX 页数:18 大小:242.77KB
下载 相关 举报
01背包动态规划回溯和背包贪心实验报告.docx_第1页
第1页 / 共18页
01背包动态规划回溯和背包贪心实验报告.docx_第2页
第2页 / 共18页
01背包动态规划回溯和背包贪心实验报告.docx_第3页
第3页 / 共18页
01背包动态规划回溯和背包贪心实验报告.docx_第4页
第4页 / 共18页
01背包动态规划回溯和背包贪心实验报告.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

01背包动态规划回溯和背包贪心实验报告.docx

《01背包动态规划回溯和背包贪心实验报告.docx》由会员分享,可在线阅读,更多相关《01背包动态规划回溯和背包贪心实验报告.docx(18页珍藏版)》请在冰豆网上搜索。

01背包动态规划回溯和背包贪心实验报告.docx

01背包动态规划回溯和背包贪心实验报告

 

西安郵電學院

算法设计与分析课内试验报告

题目:

0-1背包(动态规划、回溯)和背包(贪心)

院系名称:

计算机学院

专业名称:

软件工程专业

班级:

0903班

学生姓名:

张桥

学号(8位):

04095091(23)

指导教师:

陈琳

时间:

2011年12月

一.设计目的

通过上机实验:

深刻理解和掌握0-1背包(动态规划算法、回溯算法)和背包(贪心算法)的问题描述、算法设计思想、程序设计、算法复杂性分析、他们的区别及联系。

二.设计内容

1问题的描述

(1)0-1背包问题

给定n种物品和一背包。

物品i的重量是wi,其价值为vi,背包的容量为c。

问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大

(2)背包问题与0-1背包问题类似,所不同的是在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1<=i<=n。

2算法设计思想

(1)0-1背包问题

动态规划法:

是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。

在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。

依次解决各子问题,最后一个子问题就是初始问题的解。

由于动态规划解决的问题多数有重叠子问题这个特点,为减少重复计算,对每一个子问题只解一次,将其不同阶段的不同状态保存在一个二维数组中。

设所给0-1背包问题的子问题的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。

由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的递归式如下。

 

 

回溯法:

在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。

算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。

如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。

 

(2)背包问题

贪心算法:

首先计算每种物品单位重量的价值Vi/Wi,然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。

若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。

依此策略一直地进行下去,直到背包装满为止。

三.测试数据及运行结果

1.正常测试数据(3组)及运行结果

0-1背包问题:

动态规划法:

回溯法:

背包问题:

贪心算法:

四.调试情况,设计技巧及体会

本次的实验大体理解和掌握0-1背包(动态规划算法、回溯算法)和背包(贪心算法)的问题描述、算法设计思想、程序设计、算法复杂性分析、他们的区别及联系。

通过本次上机实验,我对0-1背包(动态规划算法、回溯算法)和背包(贪心算法)有了更为深刻的了解,利用动态规划算法、回溯算法和贪心可以将问题简化,这有助于我们在实际问题中解决一些复杂性较大的问题,提高程序的运行效率。

但要注意他们的区别与不同的应用场景。

五.源代码

1)0-1背包:

动态规划法:

#include<>

#defineMAX20

voidKnapsack(int*value,int*weight,intcolumn,intlength,int(*middle)[MAX]);

voidTraceBack(int(*middle)[MAX],int*weight,intcolumn,intlength,int*x);

intMax(intx,inty);

intMin(intx,inty);

intMin(intx,inty)

{

returnx<=yx:

y;

}

intMax(intx,inty)

{

returnx>=yx:

y;

}

voidTraceBack(int(*middle)[MAX],int*weight,intcolumn,intlength,int*x)

{

inti;

for(i=1;i

if(middle[i][column]==middle[i+1][column])

x[i]=0;

else

{

x[i]=1;

column-=weight[i];

}

x[length]=(middle[length][column]1:

0);

}

voidKnapsack(int*value,int*weight,intcolumn,intlength,int(*middle)[MAX])

{

inti,j,jMax=Min(weight[length]-1,column);

for(j=0;j<=jMax;j++)

middle[length][j]=0;

for(j=weight[length];j<=column;j++)

middle[length][j]=value[length];

for(i=length-1;i>1;i--)

{

jMax=Min(weight[i]-1,column);

for(j=0;j<=jMax;j++)

middle[i][j]=middle[i+1][j];

for(j=weight[i];j<=column;j++)

middle[i][j]=Max(middle[i+1][j],middle[i+1][j-weight[i]]+value[i]);

}

middle[1][column]=middle[2][column];

if(column>=weight[1])

middle[1][column]=Max(middle[1][column],middle[2][column-weight[1]]+value[1]);

}

voidmain(void)

{

inti,length,column,count=0,weight[MAX],value[MAX],x[MAX]={0},middle[MAX][MAX]={0};

printf("请输入背包总容量:

\n");

scanf("%d",&column);

printf("请输入物品个数:

\n");

scanf("%d",&length);

if(length<1)

{

printf("输入错误!

\n");

return;

}

for(i=1;i<=length;i++)

{

printf("请输入第%d个物品的重量及价值:

\n",i);

scanf("%d%d",weight+i,value+i);

}

Knapsack(value,weight,column,length,middle);

TraceBack(middle,weight,column,length,x);

printf("Result:

\n");

for(i=1;i<=length;i++)

if(x[i])

printf("Number:

%d,",i);

printf("\n");

}

回溯法:

#include<>

#include<>

#include<>

typedefstructgoods

{

intnum;

double*value;

double*weight;

int*location;

doublecolumn;

doublecurrentWeight;

doublecurrentValue;

doublebestValue;

}GOODS;

voidKnapsack(GOODS*goods,inti);

doubleBound(GOODS*goods,inti);

voidSwapDouble(double*m,double*n);

voidSwapInt(int*m,int*n);

voidSort(GOODS*goods);

voidSort(GOODS*goods)

{

inti,j;

double*temp;

temp=(double*)malloc(sizeof(goods->num+1));

for(i=1;i<=goods->num;i++)

temp[i]=goods->value[i]/goods->weight[i];

for(i=1;inum;i++)

{

for(j=i+1;j<=goods->num;j++)

{

if(temp[i]

{

SwapDouble(&temp[i],&temp[j]);

SwapDouble(&goods->weight[i],&goods->weight[j]);

SwapDouble(&goods->value[i],&goods->value[j]);

SwapInt(&goods->location[i],&goods->location[j]);

}

}

}

}

voidSwapInt(int*m,int*n)

{

inttemp;

temp=*m;

*m=*n;

*n=temp;

}

voidSwapDouble(double*m,double*n)

{

doubletemp;

temp=*m;

*m=*n;

*n=temp;

}

doubleBound(GOODS*goods,inti)

{

doubleleftWeight=goods->column-goods->currentWeight;

doublebound=goods->currentValue;

while(i<=goods->num&&goods->weight[i]<=leftWeight)

{

leftWeight-=goods->weight[i];

bound+=goods->value[i];

i++;

}

if(i<=goods->num)

bound+=goods->value[i]*leftWeight/goods->weight[i];

returnbound;

}

voidKnapsack(GOODS*goods,inti)

{

if(i>goods->num)

{

goods->bestValue=goods->currentValue;

return;

}

if(goods->currentWeight+goods->weight[i]<=goods->column)

{

goods->location[i]=1;

goods->currentWeight+=goods->weight[i];

goods->currentValue+=goods->value[i];

Knapsack(goods,i+1);

goods->currentWeight-=goods->weight[i];

goods->currentValue-=goods->value[i];

}

if(Bound(goods,i+1)>goods->bestValue)

{

goods->location[i]=0;

Knapsack(goods,i+1);

}

}

voidmain(void)

{

inti;

doubletotalValue,totalWeight,sumWeight;

GOODS*goods=NULL;

totalValue=totalWeight=sumWeight=;

if(!

(goods=(GOODS*)malloc(sizeof(GOODS))))

{

printf("内存分配失败\n");

exit(0);

}

goods->currentValue=goods->currentWeight=goods->bestValue=;

printf("请输入背包最大重量:

\n");

scanf("%lf",&goods->column);

printf("请输入可选物品数量:

\n");

scanf("%d",&goods->num);

if(!

(goods->value=(double*)malloc(sizeof(double)*(goods->num+1))))

{

printf("内存分配失败\n");

exit(0);

}

if(!

(goods->weight=(double*)malloc(sizeof(double)*(goods->num+1))))

{

printf("内存分配失败\n");

exit(0);

}

if(!

(goods->location=(int*)malloc(sizeof(int)*(goods->num+1))))

{

printf("内存分配失败\n");

exit(0);

}

for(i=1;i<=goods->num;i++)

goods->location[i]=0;

for(i=1;i<=goods->num;i++)

{

printf("输入第%d号物品的重量和价值:

\n",i);

scanf("%lf%lf",&goods->weight[i],&goods->value[i]);

totalValue+=goods->value[i];

totalWeight+=goods->weight[i];

}

Sort(goods);

printf("\n排序后的物品内容如下:

\n");

printf("\n背包最大能装的重量为:

%.2lf\n\n",goods->column);

for(i=1;i<=goods->num;i++)

printf("第%d号物品重:

%.2lf,价值:

%.2lf\n",i,goods->weight[i],goods->value[i]);

printf("\n所有物品总重量为:

%.2lf,总价值为:

%.2lf\n\n",totalWeight,totalValue);

Knapsack(goods,1);

printf("\n可将以下物品装入背包,使背包装的物品价值最大:

\n");

for(i=1;i<=goods->num;i++)

if(goods->location[i])

{

printf("第%d号物品,重量:

%.2lf,价值:

%.2lf\n",i,goods->weight[i],goods->value[i]);

sumWeight+=goods->weight[i];

}

printf("\n背包中物品最大重量为:

%.2lf,最大价值为:

%.2lf\n",sumWeight,goods->bestValue);

}

 

2)背包问题:

贪心算法:

#include<>

#defineMAX10

voidKnapsack(int*value,int*weight,intcolumn,intlength,double(*middle)[MAX]);

voidSort(double(*middle)[MAX],intlength);

voidSwap(double*m,double*n);

voidSwap(double*m,double*n)

{

doubletemp;

temp=*m;

*m=*n;

*n=temp;

}

voidSort(double(*middle)[MAX],intlength)

{

inti,j;

for(i=0;i

{

for(j=i+1;j

{

if(middle[1][i]

{

Swap(&middle[0][j],&middle[0][i]);

Swap(&middle[1][j],&middle[1][i]);

}

}

}

}

voidKnapsack(int*value,int*weight,intcolumn,intlength,double(*middle)[MAX])

{

inti,leftColumn=column,temp;

for(i=0;i

{

middle[0][i]=i+1;

middle[1][i]=value[i]*/weight[i];

}

Sort(middle,length);

for(i=0;leftColumn>0&&i

{

temp=weight[(int)middle[0][i]-1];

if(temp<=leftColumn)

{

leftColumn-=temp;

middle[2][i]=temp;

}

else

{

middle[2][i]=leftColumn;

break;

}

}

}

voidmain(void)

{

inti,length,column,count=0,weight[MAX],value[MAX];

doublemiddle[MAX][MAX]={0},sum=;

printf("请输入背包总容量:

\n");

scanf("%d",&column);

printf("请输入物品个数:

\n");

scanf("%d",&length);

if(length<1)

{

printf("输入错误!

\n");

return;

}

for(i=0;i

{

printf("请输入第%d个物品的重量及价值:

\n",i+1);

scanf("%d%d",weight+i,value+i);

}

Knapsack(value,weight,column,length,middle);

printf("Result:

\n");

for(i=0;i

if(middle[2][i])

{

printf("Number:

%d,Weight:

%.2lf\n",(int)middle[0][i],middle[2][i]);

sum+=middle[2][i]*middle[1][i];

}

printf("SumValue:

%.2lf",sum);

printf("\n");

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1