C++数据结构--背包问题
2013-08-11 09:49
381 查看
1.背包问题是最优化问题的一个具体例子
问题可以描述为:
给定一组物品,每种物品都有自己的大小和价格,在限定的总大小内,我们如何选择,才能使得物品的总价格最高。
背包问题有几个版本,这里只研究0/1版本,即需要作出决策来选择(1)或抛弃(0)集合中的一个物品。
Example:给出5个物品,背包容量为12
问题求解过程图解
矩阵列下标索引代表背包大小,矩阵每个横坐标对应着一个物品,值代表背包加入物品后的值,
当背包大小足够时,并且加入的新物品能比背包存储相同容量的原有物品的值大,就加入物品
具体计算方法为:当matrix[i-1][cap-item.size]+item.value大于matrix[i-1][cap]时,就加入物品
[b] 矩阵每一行都记录着每加入一个物品每个容量对应的最优解[/b]
背包问题的最优解为矩阵最后一行最后一个元素
step1:加入物品1
step2-step3:加入物品2,3
....
实现代码:
#include<iostream>
#include<iomanip>
#include<vector>
using namespace std;
class item
{
public:
int size; //物品大小
int val;
//物品价值
item(int s=0,int v=0):size(s),val(v){}
};
class knapsack
{
private:
vector<item> itemList;
//物品列表
int capacity;
//背包总大小
vector<vector<int>> matrix;
//存储自底向上计算过程的解
void buildMaxValMatrix(); //实现背包问题的解
public:
knapsack(vector<item> &v,int cpt):itemList(v),capacity(cpt),matrix(v.size()+1,
vector<int> (cpt+1,0))
{
buildMaxValMatrix();
}
void showMatrix();
//输出矩阵
void showKnapsack();
//输出被选入的背包信息
};
void knapsack::buildMaxValMatrix()
{
int numItem=itemList.size();
//物品总数
int tempMax=0;
int remainder=0;
for(int i=1;i<=numItem;i++)
//遍历物品
{
for(int cpcity=1;cpcity<=capacity;cpcity++)
//遍历背包大小
{
matrix[i][cpcity]=matrix[i-1][cpcity];
//保持默认的最大值
remainder=cpcity-itemList[i-1].size;
//加入新物品后背包剩余大小
if(remainder>=0)
{
tempMax=matrix[i-1][remainder]+itemList[i-1].val;
if(tempMax>matrix[i-1][cpcity])
//更新最大值
matrix[i][cpcity]=tempMax;
}
}
}
}
void knapsack::showMatrix()
{
for(vector<int> v:matrix)
{
for(int x:v)
cout<<setw(3)<<x<<ends;
cout<<endl;
}
}
void knapsack::showKnapsack()
{
int i=itemList.size();
int cpcity=capacity;
cout<<"optimal solution is: "<<matrix[i][capacity]<<endl;
cout<<"contain knapsacks: "<<endl;
for(;i>0;i--)
//从矩阵最后一行往前遍历
{
if(matrix[i][cpcity]!=matrix[i-1][cpcity]) //该行不等于前一行的最优解,说明有新物品加入背包
{
cout<<"knapsack : "<<i<<ends //输出物品信息
<<"size : "<<itemList[i-1].size<<ends
<<"value: "<<itemList[i-1].val<<endl;
cpcity-=itemList[i-1].size;
// 背包剩余大小
}
}
cout<<"remainding capacity : "<<cpcity<<endl; //未被利用的背包大小
}
int main ()
{
vector<item> v{item(2,1),item(3,4),item(4,3),item(5,6),item(6,8)};
knapsack kps(v,12);
kps.showMatrix();
cout<<endl;
kps.showKnapsack();
return 0;
}
运行结果:
问题可以描述为:
给定一组物品,每种物品都有自己的大小和价格,在限定的总大小内,我们如何选择,才能使得物品的总价格最高。
背包问题有几个版本,这里只研究0/1版本,即需要作出决策来选择(1)或抛弃(0)集合中的一个物品。
Example:给出5个物品,背包容量为12
问题求解过程图解
矩阵列下标索引代表背包大小,矩阵每个横坐标对应着一个物品,值代表背包加入物品后的值,
当背包大小足够时,并且加入的新物品能比背包存储相同容量的原有物品的值大,就加入物品
具体计算方法为:当matrix[i-1][cap-item.size]+item.value大于matrix[i-1][cap]时,就加入物品
[b] 矩阵每一行都记录着每加入一个物品每个容量对应的最优解[/b]
背包问题的最优解为矩阵最后一行最后一个元素
step1:加入物品1
step2-step3:加入物品2,3
....
实现代码:
#include<iostream>
#include<iomanip>
#include<vector>
using namespace std;
class item
{
public:
int size; //物品大小
int val;
//物品价值
item(int s=0,int v=0):size(s),val(v){}
};
class knapsack
{
private:
vector<item> itemList;
//物品列表
int capacity;
//背包总大小
vector<vector<int>> matrix;
//存储自底向上计算过程的解
void buildMaxValMatrix(); //实现背包问题的解
public:
knapsack(vector<item> &v,int cpt):itemList(v),capacity(cpt),matrix(v.size()+1,
vector<int> (cpt+1,0))
{
buildMaxValMatrix();
}
void showMatrix();
//输出矩阵
void showKnapsack();
//输出被选入的背包信息
};
void knapsack::buildMaxValMatrix()
{
int numItem=itemList.size();
//物品总数
int tempMax=0;
int remainder=0;
for(int i=1;i<=numItem;i++)
//遍历物品
{
for(int cpcity=1;cpcity<=capacity;cpcity++)
//遍历背包大小
{
matrix[i][cpcity]=matrix[i-1][cpcity];
//保持默认的最大值
remainder=cpcity-itemList[i-1].size;
//加入新物品后背包剩余大小
if(remainder>=0)
{
tempMax=matrix[i-1][remainder]+itemList[i-1].val;
if(tempMax>matrix[i-1][cpcity])
//更新最大值
matrix[i][cpcity]=tempMax;
}
}
}
}
void knapsack::showMatrix()
{
for(vector<int> v:matrix)
{
for(int x:v)
cout<<setw(3)<<x<<ends;
cout<<endl;
}
}
void knapsack::showKnapsack()
{
int i=itemList.size();
int cpcity=capacity;
cout<<"optimal solution is: "<<matrix[i][capacity]<<endl;
cout<<"contain knapsacks: "<<endl;
for(;i>0;i--)
//从矩阵最后一行往前遍历
{
if(matrix[i][cpcity]!=matrix[i-1][cpcity]) //该行不等于前一行的最优解,说明有新物品加入背包
{
cout<<"knapsack : "<<i<<ends //输出物品信息
<<"size : "<<itemList[i-1].size<<ends
<<"value: "<<itemList[i-1].val<<endl;
cpcity-=itemList[i-1].size;
// 背包剩余大小
}
}
cout<<"remainding capacity : "<<cpcity<<endl; //未被利用的背包大小
}
int main ()
{
vector<item> v{item(2,1),item(3,4),item(4,3),item(5,6),item(6,8)};
knapsack kps(v,12);
kps.showMatrix();
cout<<endl;
kps.showKnapsack();
return 0;
}
运行结果:
相关文章推荐
- C++实现多目标遗传算法(0/1背包问题)
- 最简单的0-1背包问题c++代码实例及运行结果
- 算法与数据结构-贪心算法及背包问题解决
- dynamic programming --knapsack problem 背包问题(c++实现)
- c++实现0-1背包问题完整源码(动态…
- 最简单的0-1背包问题c++代码实例及运行结果
- 数据结构(18)栈典型问题之C++实现括号匹配
- 用贪心算法求解普通背包问题的C++代码
- 混合三种背包问题c++
- C++:背包问题总结
- Charm Bracelet poj 3624 (01) 背包问题 c++
- 背包问题C++程序
- C++:暴力搜索全排列解决背包问题
- 从递归问题继续看c++数据结构
- C++动态规划算法之0-1背包问题
- 01背包问题的C/C++实现
- 用C++链式栈解决数据结构中的括号匹配问题。
- 所有背包问题代码总结 C++
- 算法与数据结构 - 0/1背包问题
- 【数据结构_动态规划_背包问题_0963】小偷的背包