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 ...
随机推荐
- jquery添加插件
转自:https://www.cnblogs.com/joey0210/p/3408349.html 前言 如今做web开发,jquery 几乎是必不可少的,就连vs神器在2010版本开始将Jquer ...
- Python之request模块-基础用法
Request模块参考中文手册:https://requests.readthedocs.io/zh_CN/latest/ Request模块 1.查看pip已装包(模块)的安装信息(模块的路径.版本 ...
- Spring通过配置类加载实体bean
以下4个java类都在都一个包下: 1.定义接口 public interface AA { void play(); } 2.定义实体bean //组件注解,表明该类是一个组件 @Component ...
- Linux Firewalld 基础介绍
互联网上提供了各种网络服务,而防火墙可以设置各种规则来限制访问,保护服务器. 概述 Linux的防火墙体系主要工作在网络层,针对TCP/IP数据包实施过滤和限制,属于典型的包过滤防火墙. Linux系 ...
- Django框架(九)-- 多表操作:一对一、一对多、多对多的增删改,基于对象/双下划线的跨表查询、聚合查询、分组查询、F查询与Q查询
一.创建多表模型 一对一:OneToOneField 一对多:ForeignKey 多对多:ManyToManyField 创建表时,会自动添加一个nid字段,并且自增,所以id可以不用手动创建 On ...
- springboot搭建dubbo+zookeeper简单案例
背景:只是自己使用单机版zookeeper搭建dubbo的一个学习案例,记录成功的过程 1.搭建zookeeper坏境 使用docker来构建环境 1.1 拉取镜像:docker pull zooke ...
- Nginx 核心配置-新建一个web站点
Nginx 核心配置-新建一个web站点 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Nginx基础配置常用参数说明 [root@node101.yinzhengjie.or ...
- 机器学习——k-均值算法(聚类)
文章目录 k-均值(k-means)聚类 1.k-均值算法 2.k-均值算法的代价函数 3.k-均值算法步骤 4.初始化聚类中心点和聚类个数 5.sklearn实现k-means算法 k-均值(k-m ...
- 性能测试基础---jmeter基础
·Jmeter的脚本构成: Jmeter的脚本是由很多不同的组件构成,在Jmeter中,组件可以分为以下几类: ·测试计划: 是默认存在的组件,所有的Jmeter的组件都是依赖于测试计划的. 在这个组 ...
- 织梦dedecms后台文件media_add.php任意上传漏洞解决办法
织梦在安装到阿里云服务器后阿里云后台会提示media_add.php后台文件任意上传漏洞,引起的文件是后台管理目录下的media_add.php文件,下面跟大家分享一下这个漏洞的修复方法: 首先找到并 ...