蛮力法、动态规划法、回溯法和分支限界法求解01背包问题
一、实验内容:
分别用蛮力法、动态规划法、回溯法和分支限界法求解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];< …… 此处隐藏:6947字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [综合文档]应答器设备技术规范(征求意见稿)A1
- [综合文档]教师 2012年高考政治试题按考点分类汇
- [综合文档]保险公司的总经理助理竞职演说
- [综合文档]卫生应急大练兵大比武活动考试--题库(
- [综合文档]徐州经济技术开发区总体规划环境影响报
- [综合文档]汉语拼音表(带声调)
- [综合文档]二年级 上 思维训练( 1~18)
- [综合文档]特色学校五年发展规划
- [综合文档]机床经常出现报警“X1轴定位监控”
- [综合文档]《电子技术基础》21.§5—2、3、4 习题
- [综合文档]浙江省深化普通高中课程改革
- [综合文档]CRISP原理 - 图文
- [综合文档]2017年电大社会调查研究与方法形考答案
- [综合文档]浅析建筑施工安全毕业论文
- [综合文档]《回忆我的母亲》名师教案
- [综合文档]装饰装修工程监理规划
- [综合文档]三下乡心得体会-文艺
- [综合文档]柱计算长度系数 - 图文
- [综合文档]全流程思考,提高燃电系统热电转换率--
- [综合文档]2018年嘉定区中考物理一模含答案
- 433M车库门滚动码遥控器
- 8、架空线路施工规范
- 大学四年声乐学习的体会
- 新北师大版五年级数学上册《轴对称再认
- 部编版五年级上册语文第六单元小结复习
- 小学六年级英语形容词用法
- 第2课 抗美援朝保家卫国 课件01(岳麓版
- 2015年天津大学运筹学基础考研真题,考
- 微机计算机控制技术课后于海生(第2版)
- 安全教育实践活动
- Delphi程序设计教程_第1章_Delphi概述
- 第八讲 工业革命与启蒙运动
- 《中华人民共和国药典》2005年版二部勘
- 科粤版九年级化学2.3构成物质的微粒(1)
- 西师大版数学三年级下册《长方形、正方
- ch6_冒泡排序演示
- 第4章 冲裁模具设计
- 浙江中小民营企业员工流失论文[终稿]
- 再议有线数字电视市场营运模式
- 昆明供水工程监理大纲




