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 ...
随机推荐
- flink batch wordcount
1.POJO方式 public class WordCountPojo { public static class Word{ private String word; private int fre ...
- 安装Python,输入pip命令报错———pip Fatal error in launcher: Unable to create process using
今天把Python的安装位置也从C盘剪切到了D盘, 然后修改了Path环境变量中对应的盘符:D:\Python27\;D:\Python27\Scripts; 不管是在哪个目录,Python可以执行了 ...
- MySQL连接超时处理
1.由于MySQL默认是8小时的wait_timeout,当超过8小时的连接时间后,在JAVA中调用将出现如下报错 SEVERE EXCEPTION com.mysql.jdbc.exceptions ...
- QElapsedTimer定时器记录程序执行时间
QElapedTimer类提供了一种快速计算运行时间的方法,从Qt4.7引入. QElapsedTimer类通常用于快速计算两个事件之间经过了多少时间.它的API与QTime相似,因此可以将正在使用的 ...
- 【HttpServlet】HttpServlet类
创建时间:6.15 HttpServlet 但在实际开发中,我们不会直接去实现Servlet接口,因为那样需要覆盖的方法太多, 我们一般创建类继承HttpServlet 实现步骤: 1)创建类继 ...
- 重复的DNA序列[哈希表] LeetCode.187
所有 DNA 由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:"ACGAATTCCG".在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助. 编写一个函数 ...
- php观察者模式(observer pattern)
... <?php /* The observer pattern implements a one-too-many dependency between objects. The objec ...
- jquery 统计统计子标签的个数
本文实例讲述了jQuery获得子元素个数的方法.分享给大家供大家参考.具体分析如下://获取id=div1下的子元素的个数$('#div1').children().length;//获取id=div ...
- js如何安全的扩展系统函数
如果直接使用原型扩展系统函数,可能会和其他人的代码相互冲突 为了防止出现冲突,可以使用如下方法进行扩展: function MyArray(){ this.Name="MyArray&quo ...
- Python——IO多路复用之select模块select方法
Python——IO多路复用之select模块select方法 使用select模块的select方法实现Python——IO多路复用 实现同时将终端输入的文本以及客户端传输的文本写入文本文件中: w ...