教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 文库大全 > 外语考试 >

蛮力法、动态规划法、回溯法和分支限界法求解01背包问题

来源:网络收集 时间:2026-04-30
导读: 一、实验内容: 分别用蛮力法、动态规划法、回溯法和分支限界法求解0/1背包问题。 注:0/1背包问题:给定n种物品和一个容量为C的背包,物品i的重量 是wi,其价值为vi,背包问题是如何使选择装入背包内的物品,使得装入背 包中的物品的总价值最大。其中,每种

一、实验内容:

分别用蛮力法、动态规划法、回溯法和分支限界法求解0/1背包问题。

注:0/1背包问题:给定n种物品和一个容量为C的背包,物品i的重量

是wi,其价值为vi,背包问题是如何使选择装入背包内的物品,使得装入背

包中的物品的总价值最大。其中,每种物品只有全部装入背包或不装入背包

两种选择。

二、所用算法的基本思想及复杂度分析:

1.蛮力法求解0/1背包问题:

1)基本思想:

对于有n种可选物品的0/1背包问题,其解空间由长度为n的0-1

向量组成,可用子集数表示。在搜索解空间树时,深度优先遍历,搜索每

一个结点,无论是否可能产生最优解,都遍历至叶子结点,记录每次得

到的装入总价值,然后记录遍历过的最大价值。

2)代码:

#include<iostream>

#include<algorithm>

using namespace std;

#define N 100 //最多可能物体数

struct goods //物品结构体

{

int sign; //物品序号

int w; //物品重量

int p; //物品价值

}a[N];

bool m(goods a,goods b)

{

return (a.p/a.w)>(b.p/b.w);

}

int max(int a,int b)

{

return a<b?b:a;

}

int n,C,bestP=0,cp=0,cw=0;

int X[N],cx[N];

/*蛮力法求解0/1背包问题*/

int Force(int i)

{

if(i>n-1){

if(bestP<cp&&cw+a[i].w<=C){

for (int k=0;k<n;k++) X[k]=cx[k];//存储最优路径

bestP=cp;

}

return bestP;

}

cw=cw+a[i].w;

cp=cp+a[i].p;

cx[i]=1; //装入背包

Force(i+1);

cw=cw-a[i].w;

cp=cp-a[i].p;

cx[i]=0; //不装入背包

Force(i+1);

return bestP;

}

int KnapSack1(int n,goods a[],int C,int x[])

{

Force(0);

return bestP;

}

int main()

{

goods b[N];

printf("物品种数n: ");

scanf("%d",&n); //输入物品种数

printf("背包容量C: ");

scanf("%d",&C); //输入背包容量

for (int i=0;i<n;i++) //输入物品i的重量w及其价值v

{

printf("物品%d的重量w[%d]及其价值v[%d]:

",i+1,i+1,i+1);

scanf("%d%d",&a[i].w,&a[i].p);

b[i]=a[i];

}

int sum1=KnapSack1(n,a,C,X);//调用蛮力法求0/1背包问题

printf("蛮力法求解0/1背包问题:\nX=[ ");

for(i=0;i<n;i++)

cout<<X[i]<<" ";//输出所求X[n]矩阵

printf("] 装入总价值%d\n",sum1);

bestP=0,cp=0,cw=0;//恢复初始化

}

3)复杂度分析:

蛮力法求解0/1背包问题的时间复杂度为:T(n) O(2n)。

2.动态规划法求解0/1背包问题:

1)基本思想:

令V(i,j)表示在前i(1 i n)个物品中能够装入容量为j(1 j C)的

背包中的物品的最大值,则可以得到如下动态函数:

V(i,0) V(0,j) 0

V(i 1,j)(j wi) V(i,j) V(i 1,j),V(i 1,j wi) vi (j wi) max

按照下述方法来划分阶段:第一阶段,只装入前1个物品,确定在

各种情况下的背包能够得到的最大价值;第二阶段,只装入前2个物品,

确定在各种情况下的背包能够得到的最大价值;以此类推,直到第n个

阶段。最后,V(n,C)便是在容量为C的背包中装入n个物品时取得的最

大价值。

2)代码:

#include<iostream>

#include<algorithm>

using namespace std;

#define N 100 //最多可能物体数

struct goods

{ //物品结构体

int sign; //物品序号

int w; //物品重量

int p; //物品价值

}a[N];

bool m(goods a,goods b)

{

return (a.p/a.w)>(b.p/b.w);

}

int max(int a,int b)

{

return a<b?b:a;

}

int n,C,bestP=0,cp=0,cw=0;

int X[N],cx[N];

int KnapSack2(int n,goods a[],int C,int x[])

{

int V[N][10*N]; for(int i=0;i<=n;i++) V[i][0]=0; for(int j=0;j<=C;j++) V[0][j]=0; for(i=1;i<=n;i++) for(j=1;j<=C;j++) //初始化第0列 //初始化第0行 //计算第i行,进行第i次迭代

if(j<a[i-1].w) V[i][j]=V[i-1][j]; else V[i][j]=max(V[i-1][j],V[i-1][j-a[i-1].w]+a[i-1].p); j=C; //求装入背包的物品 for (i=n;i>0;i--) { if (V[i][j]>V[i-1][j]){ x[i-1]=1; j=j-a[i-1].w; x[i-1]=0; } else } return V[n][C]; //返回背包取得的最大价值

}

int main()

{

goods b[N];

printf("物品种数n: ");

scanf("%d",&n); //输入物品种数 printf("背包容量C: "); scanf("%d",&C); //输入背包容量 for (int i=0;i<n;i++) //输入物品i的重量w及其价值v { printf("物品%d的重量w[%d]及其价值v[%d]: ",i+1,i+1,i+1); scanf("%d%d",&a[i].w,&a[i].p); b[i]=a[i];

}

int sum2=KnapSack2(n,a,C,X);//调用动态规划法求0/1背包问题

printf("动态规划法求解0/1背包问题:\nX=[ ");

for(i=0;i<n;i++) cout<<X[i]<<" ";//输出所求X[n]矩阵 printf("] 装入总价值%d\n",sum2); for (i=0;i<n;i++) { a[i]=b[i]; }//恢复a[N]顺序

}

3)复杂度分析:

动态规划法求解0/1背包问题的时间复杂度为:T(n) O(n C)。

3.回溯法求解0/1背包问题:

1)基本思想:

回溯法:为了避免生成那些不可能产生最佳解的问题状态,要不断

地利用限界函数(bounding function)来处死那些实际上不可能产生所

需解的活结点,以减少问题的计算量。这种具有限界函数的深度优先生

成法称为回溯法。

对于有n种可选物品的0/1背包问题,其解空间由长度为n的0-1

向量组成,可用子集数表示。在搜索解空间树时,只要其左儿子结点是一

个可行结点,搜索就进入左子树。当右子树中有可能包含最优解时就进

入右子树搜索。

2)代码:

#include<iostream>

#include<algorithm>

using namespace std;

#define N 100 //最多可能物体数

struct goods //物品结构体

{

int sign; //物品序号 int w; //物品重量

int p; //物品价值

}a[N];

bool m(goods a,goods b)

{

return (a.p/a.w)>(b.p/b.w);

}

int max(int a,int b)

{

return a<b?b:a;

}

int n,C,bestP=0,cp=0,cw=0;

int X[N],cx[N];< …… 此处隐藏:2952字,全部文档内容请下载后查看。喜欢就下载吧 ……

蛮力法、动态规划法、回溯法和分支限界法求解01背包问题.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wenku/117169.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)