动态规划——0-1背包
来源:互联网 发布:伊藤网络超市 编辑:程序博客网 时间:2024/05/30 23:27
问题描述
0-1背包问题可描述为:n个物品和1个背包。对物品i,其价值为vi,重量为wi,背包的容量为W。如何选取物品装入背包,使背包中所装入的物品的总价值最大?
约束条件:
目标函数:
于是,问题归结为寻找一个满足约束条件(4-7),并使目标函数(4-8)达到最大的解向量X=(x1, x2,…, xn)。
最优子结构性质分析
- 假设(x1, x2,…, xn)是所给0-1背包问题的一个最优解,则(x2,…, xn)是下面相应子问题的一个最优解:
- 约束条件:
- 目标函数:
建立最优值的递归关系
- 令C[i][j]=
- C[0][j]=C[i][0]=0
算法设计——求装入背包的最大价值
- 步骤1:设计算法所需的数据结构。采用数组w[n]来存放n个物品的重量;数组v[n]来存放n个物品的价值,背包容量为W,数组C[n+1][W+1]来存放每一次迭代的执行结果;数组x[n]用来存储所装入背包的物品状态;
- 步骤2:初始化。按式(4-10)初始化数组C;
- 步骤3:循环阶段。按式(4-11)确定前i个物品能够装入背包的情况下得到的最优值;
– 步骤3-1:i=1时,求出C[1][j],1≤j≤W;
– 步骤3-2:i=2时,求出C[2][j],1≤j≤W;
– 依此类推,直到……
– 步骤3-n:i=n时,求出C[n][W]。此时,C[n][W]便是最优值;
算法设计——确定装入背包的具体物品
从C[n][W]的值向前推,如果C[n][W]> C[n-1][W],表明第n个物品被装入背包,则xn=1,前n-1个物品被装入容量为W-wn的背包中;否则,第n个物品没有被装入背包,则xn=0,前n-1个物品被装入容量为W的背包中。依此类推,直到确定第1个物品是否被装入背包中为止。由此,得到下面关系式:
按照上式,从C[n][W]的值向前倒推,即j初始为W,i初始为n,即可确定装入背包的具体物品。
构造实例
有5个物品,其重量分别为2,2,6,5,4,价值分别为6,3,5,4,6。背包容量为10,物品不可分割,求装入背包的物品和获得的最大价值。
算法描述
Int KnapSack(int n, int W, int w[ ],int v[ ]){ int I,j,c[n][W],x[n]; for(i=0;i<=n;i++) c[i][0]=0; for(i=0;i<=W;i++) c[0][i]=0; for(i=1;i<=n;i++) for(j=1;j<=W;j++) if(j<w[i]) c[i][j]=c[i-1][j]; else c[i][j]=max(c[i-1][j],c[i-1][j-w[i]]+v[i]);//构造最优解 j=W; for(i=n;i>0;i--) if(c[i][j]>c[i-1][j]) { x[i]=1; j-=w[i];} else x[i]=0; return c[n][w];}
代码实现
#include <iostream>using namespace std;int KnapSack(int W,int n,int *w,int *v,int **c);int main(){ int W,n,*w,*v,**c;//W背包总重量,n物品个数,*w 物品重量,*v物品价值 **c最优解 cout<<"请输入背包最大重量和物品个数: "; cin>>W>>n; w = new int[n+1]; v = new int[n+1]; cout<<"请输入各个物品重量和价值"<<endl; for(int i=1;i<=n;i++){ cin>>w[i]; } for(int i=1;i<=n;i++){ cin>>v[i]; } c = new int*[n+1]; for(int i=0;i<=n;i++){ c[i] = new int[W+1]; } KnapSack(W,n,w,v,c); return 0;}int KnapSack(int W,int n,int *w,int *v,int **c){ int i,j,x[n]; for(i=0;i<=n;i++) c[i][0] = 0; for(i=0;i<=W;i++) c[0][i] = 0; for(i=1;i<=n;i++){ for(j=1;j<=W;j++){ if(j<w[i]){ c[i][j] = c[i-1][j]; }else if(c[i-1][j]>c[i-1][j-w[i]]+v[i]){ c[i][j] = c[i-1][j]; }else{ c[i][j] = c[i-1][j-w[i]]+v[i]; } } } j = W; for(i=n;i>0;i--){ if(c[i][j]>c[i-1][j]){ x[i] = 1; j -= w[i]; }else{ x[i] = 0; } } cout<<"最优解为"; for(i=1;i<=n;i++){ cout<<x[i]<<" "; } cout<<endl<<"矩阵为: "<<endl;; for(i=0;i<=n;i++){ for(j=0;j<=W;j++){ cout<<c[i][j]<<" "; } cout<<endl; } return c[n][W];}
测试结果
阅读全文
0 0
- 动态规划——0-1背包
- 0-1背包——动态规划
- 动态规划——0-1背包
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划—0-1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划0—1背包问题
- 动态规划—0-1背包
- 动态规划——0/1背包问题
- 0-1背包问题——动态规划
- 动态规划——0-1背包问题
- Golang 切片拼接
- apollo mqtt 搭建
- 欢迎使用CSDN-markdown编辑器
- 信息熵,条件熵,互信息的通俗理解
- Linux下指定源ip进行ping操作
- 动态规划——0-1背包
- three.js 02-05 之相机
- Magento清除缓存(clear cache)和创建缓存(create cache)的方法
- 服务计算作业4——cloudgo(扩展任务)
- Spark
- Apple Pay 和 苹果内购买
- 九九乘法表
- 通过WebMagic认识正则表达式和XPATH
- PAT考试乙级1019(C语言实现) 重点题目