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 ...
随机推荐
- 尝试在Mac/iOS上使用tcmalloc库
概述 TCMalloc 是 Google 开发的内存分配器,在不少项目中都有使用,例如在 Golang 中就使用了类似的算法进行内存分配.它具有现代化内存分配器的基本特征:对抗内存碎片. ...
- android studio学习----添加项目依赖包补充---添加github上的开源项目为库
导入maven中的库 如果开源库作者有将代码放到Maven库中,我们可以在gradle配置中直接引入,类似如下: compile 'com.github.dmytrodanylyk.android-p ...
- 设计模式:单例(Sigleton)模式
题目:设计一个类,我们只能生成该类的一个实例. 只能生成一个实例的类是实现了Singleton(单例)模式的类型. 相关知识: 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象 ...
- Spark GraphX图计算核心算子实战【AggreagteMessage】
一.简介 参考博客:https://www.cnblogs.com/yszd/p/10186556.html 二.代码实现 package graphx import org.apache.log4j ...
- 『计算机视觉』imgaug图像增强库中部分API简介
https://github.com/aleju/imgaug 介绍一下官方demo中用到的几个变换,工程README.md已经给出了API简介,个人觉得不好理解,特此单独记录一下: import n ...
- idea 2019 集成activiti, idea activiti 新建bpmn文件, 解决idea activiti中文乱码
idea 在线安装activiti插件 1. File-->Settings 2. 点击Plugins, 右侧界面点击Marketplace后在搜索框搜索 actiBPM 注: 网络原因没有加载 ...
- 安装Ubuntu后需要做的事
卸载软件 纸牌 麻将 扫雷 数独 火狐 邮件 扫描 拍照 照片 视频 计划 日历 打印 备份 计算器 亚马逊 电源统计 音乐播放 远程桌面 To Do LibreOffice 换下载源 装机的时候下载 ...
- 大众点评评论数据抓取 反爬虫措施有css文字映射和字体库反爬虫
大众点评评论数据抓取 反爬虫措施有css文字映射和字体库反爬虫 大众点评的反爬虫手段有那些: 封ip,封账号,字体库反爬虫,css文字映射,图形滑动验证码 这个图片是滑动验证码,访问频率高的话,会出 ...
- gitlab 提示:remote: The project you were looking for could not be found.
解决: git remote remove origin git remote add origin https://your_git_user_name@git.qutoutiao.net/your ...
- Scrapy笔记05- Item详解
Scrapy笔记05- Item详解 Item是保存结构数据的地方,Scrapy可以将解析结果以字典形式返回,但是Python中字典缺少结构,在大型爬虫系统中很不方便. Item提供了类字典的API, ...