C++动态规划求解0-1背包问题
问题描述:
给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问:应该如何选择装入背包的物品,是的装入背包中物品的总价值最大?
细节须知:
暂无。
算法原理:
a.最优子结构性质
0-1背包问题具有最优子结构性质。设(y1,y2,…,yn)是所给0-1背包问题的一个最优解,则(y2,…,yn)是下面相应子问题的一个最优解。

b.递归关系
设所给0-1背包问题的子问题

的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。有0-1背包问题的最优子结构性质,可以建立如下计算m(i,j)的递归式

#include <iostream>
#include <fstream>
#include <ctime>
#include <algorithm>
#include <windows.h>
using namespace std;
#define N 10000 //int w[5] = { 0 , 2 , 3 , 4 , 5 }; //商品的体积2、3、4、5
//int v[5] = { 0 , 3 , 4 , 5 , 6 }; //商品的价值3、4、5、6
//int bagV = 8; //背包大小
int dp[N][N]; //动态规划表
//int item[5]; //最优解情况 void findMax(int k,int n,int w[],int v[]) { //动态规划
for (int i = ; i <= k; i++) {
for (int j = ; j <= n; j++) {
if (j < w[i])
dp[i][j] = dp[i - ][j];
else
dp[i][j] = max(dp[i - ][j], dp[i - ][j - w[i]] + v[i]);
}
}
} void findWhat(int i, int j,int w[],int v[],int item[]) { //最优解情况
if (i > ) {
if (dp[i][j] == dp[i - ][j]) {
item[i] = ;
findWhat(i - , j,w,v,item);
}
else if (j - w[i] >= && dp[i][j] == dp[i - ][j - w[i]] + v[i]) {
item[i] = ;
findWhat(i - , j - w[i],w,v,item);
}
}
} void print(int k,int n,int item[]) {
/*for (int i = 0; i < k+1; i++) { //动态规划表输出
for (int j = 0; j < n+1; j++) {
cout << dp[i][j] << ' ';
}
cout << endl;
}
cout << endl;*/
cout <<"The item number that should be put into the backpack is:";
for (int i = ; i < k+; i++){ //最优解输出
if(item[i] == )
cout << i << ' ';
}
cout << endl;
} int main(void)
{
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime;
LARGE_INTEGER nEndTime;
ofstream fout;
double cost;
int i,j,m,n,k;
cout << "Please enter the number of times you want to run the program:";
cin >> m;
//int object_amount[m];
//double runtime[m];
fout.open("backpack.txt",ios::app);
if(!fout){
cerr<<"Can not open file 'backpack.txt' "<<endl;
return -;
}
fout.setf(ios_base::fixed,ios_base::floatfield); //防止输出的数字使用科学计数法
srand((unsigned int)time(NULL));
for(i = ; i < m; i++){
n = rand()%;
k = rand()%;
//object_amount[i] = k;
fout<<k<<",";
int item[k];
cout << "The " << i+ << "th test's backpack lattice number is:" << n << endl;
cout << "The " << i+ << "th test's object amount is:" << k << endl;
int w[k];
int v[k];
memset(dp,,sizeof(dp));
w[] = ;
v[] = ;
for(j=;j<k;j++){
w[j]=rand()%;
v[j]=rand()%;
}
QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&nBeginTime);
findMax(k,n,w,v);
findWhat(k,n,w,v,item);
print(k,n,item);
QueryPerformanceCounter(&nEndTime);
cost=(double)(nEndTime.QuadPart - nBeginTime.QuadPart) / (double)nFreq.QuadPart;
//runtime[i]=cost;
fout<<cost<<endl;
cout<<"The running time is:"<<cost<<" s"<<endl;
}
/* fout.open("backpack.txt",ios::app);
if(!fout){
cerr<<"Can not open file 'backpack.txt' "<<endl;
return -1;
}
fout.setf(ios_base::fixed,ios_base::floatfield); //防止输出的数字使用科学计数法
for(i=0;i<m;i++){
fout<<object_amount[i]<<","<<runtime[i]<<endl;
}*/
fout.close();
cout<<"Success!"<<endl;
return ;
}
程序设计思路:
根据算法原理中所述递归关系,递归计算全部的m(i,j),得到不同情况下的最优解。
假设m[1][c]给出所要求的的0-1背包问题的最优值。相应的最优解计算如下:
如果m[1][c]=m[2][c],则x1=0;否则x1=1.当x1=0是,由m[2][c]继续构造最优解;当x1=1时,有m[2][c-w1]继续构造最优解。以此类推,可构造出相应的最优解(x1,x2,…,xn)。
时间复杂性分析:
从计算m(i,j)的递归式容易看出,对于0-1背包问题的求解算法需要O(nc)计算时间,而算法解出最优方案需要O(n)计算时间,当背包容量c很大时,算法需要的计算时间较多。
生成的数据可导入EXCEL中进行数据分析生成分析图表。
C++动态规划求解0-1背包问题的更多相关文章
- Java实现动态规划法求解0/1背包问题
摘要: 使用动态规划法求解0/1背包问题. 难度: 初级 0/1背包问题的动态规划法求解,前人之述备矣,这里所做的工作,不过是自己根据理解实现了一遍,主要目的还是锻炼思维和编程能力,同时,也是为了增进 ...
- hdu2602Bone Collector ——动态规划(0/1背包问题)
Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bone Collec ...
- 背包问题(Knapsack problem)采用动态规划求解
问题说明: 假设有一个背包的负重最多可达8公斤,而希望在背包中装入负重范围内可得之总价物品,假设是水果好了,水果的编号.单价与重量如下所示:0李子4KGNT$45001苹果5KGNT$57002橘子2 ...
- 0-1背包问题——动态规划求解【Python】
动态规划求解0-1背包问题: 问题:背包大小 w,物品个数 n,每个物品的重量与价值分别对应 w[i] 与 v[i],求放入背包中物品的总价值最大. 动态规划核心:计算并存储小问题的最优解,并将这些最 ...
- 经典递归问题:0,1背包问题 kmp 用遗传算法来解背包问题,hash表,位图法搜索,最长公共子序列
0,1背包问题:我写笔记风格就是想到哪里写哪里,有很多是旧的也没删除,代码内部可能有很多重复的东西,但是保证能运行出最后效果 '''学点高大上的遗传算法''' '''首先是Np问题的定义: npc:多 ...
- 蓝桥杯 0/1背包问题 (java)
今天第一次接触了0/1背包问题,总结一下,方便以后修改.不对的地方还请大家不啬赐教! 上一个蓝桥杯的例题: 数据规模和约定 代码: import java.util.Scanner; public ...
- 动态规划 求解 Minimum Edit Distance
http://blog.csdn.net/abcjennifer/article/details/7735272 自然语言处理(NLP)中,有一个基本问题就是求两个字符串的minimal Edit D ...
- 动态规划:HDU1059-Dividing(多重背包问题的二进制优化)
Dividing Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- 动态规划求解序列问题(LIS、JLIS)
1. 最长递增子序列 不要求位置连续:要求大小严格递增(strictly increasing) 穷举法解题 首先以每个数字为单位分割寻找最长递增子序列: int lis(const vector&l ...
随机推荐
- 中国工业的下一个十年在哪里?APS系统或将引领智能化转型
为什么众多的ERP软件公司没有推出相关产品,当然可以肯定的是并非客户没有此观念,如果一定要说,也只能说目前的需求还不是非常强烈,从ERP厂商非常急切的与APS公司合作,甚至有高价购买APS公司代码的情 ...
- android studio学习----gradle配置
转载地址:http://blog.csdn.net/loongggdroid/article/details/47037413 1.gradle的简单介绍 Gradle是可以用于Android开发的新 ...
- JavaWeb Listener之HttpSessionBindListener
HttpSessionBindListener 监听把自身这个对象绑定到HttpSession对象上.解绑 绑定到HttpSession对象上,其实就是调用session的setAttr ...
- docker在linux上的安装
docker安装在liunx环境上,我电脑用的是ubuntu系统的,需要下载对应系统的docker,我下载的是社区版,对着官方的命令敲就好了, 地址是:https://docs.docker.com/ ...
- 前后端分离-Restful最佳实践
前后端分离-Restful最佳实践 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- linux 下首次使用github 和其中遇到的问题
1首先安装git sudo apt-get install git 2配置git文件 git config --global user.name "你的用户名" git confi ...
- Scrapy的中间件(一)
中间件是Scrapy里面的一个核心概念.使用中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改,从而开发出适应不同情况的爬虫. "中间件"这个中文名字和前面章节讲到 ...
- [RN] React Native 使用 teaset(Drawer)实现侧边菜单
https://www.cnblogs.com/crazycode2/p/9537518.html
- 网络协议 7 - UDP 协议
网络协议五步登天路,我们一路迈过了物理层.链路层,今天终于到了传输层.从这一层开始,很多知识应该都是服务端开发必备的知识了,今天我们就一起来梳理下. 其实,讲到 UDP,就少不了 TCP.这俩 ...
- SDOI 2019 R2 摸鱼记
其实并没有什么动力来写这篇游记,毕竟呢,明明已经做好了被吊打的心理准备,可是当 Day 2 挂到没分时,当看到自己在高一里还排名二十时,还是有些,有些难言的滋味.学长们该走的真的都走了,就要只剩下 z ...