【算法】0/1 背包问题的最优解(C++源码)
- 一、任务描述
- 二、步骤描述
- 三、运行结果截图
- 四、源代码(C++)
一、任务描述
用蛮力法,编程求解如下0/1背包问题的最优解:
n = 7, W = 15
价值 P = {10, 5, 15, 7, 6, 18, 3}
重量 w = {2, 3, 5, 7, 1, 4, 1}
二、步骤描述
先用一个vector存放幂集,定义一个可以调用的函数PSet用于求1~n的幂集ps,再创建一个可以调用的函数Knap用于求所有方案和最佳方案的函数,最后在主函数调用。
三、运行结果截图
四、源代码(C++)
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int> > ps;//存放幂集
void PSet(int n)//求1~n的幂集ps
{
vector< vector<int> > ps1;//子幂集
vector< vector<int> >::iterator it;//幂集迭代器
vector<int> s;
ps.push_back(s);//添加{}空集合元素
for(int i=1;i<=n;i++)//循环添加1~n
{
ps1=ps;//ps1存放上一步得到的幂集
for(it=ps1.begin();it!=ps1.end();++it)
{
(*it).push_back(i);//在ps1的每个集合元素末尾添加i
}
for (it=ps1.begin();it!=ps1.end();++it)
{
ps.push_back(*it);//将ps1的每个集合元素添加到ps中
}
}
}
void Knap(int w[],int v[],int W)//求所有的方案和最佳方案
{
int count=0;//方案编号
int sumw,sumv;//当前方案的总重量和总价值
int maxi,maxsumw=0,maxsumv=0;//最佳方案的编号、总重量和总价值
vector< vector<int> >::iterator it; //幂集迭代器
vector<int>::iterator sit; //幂集集合元素迭代器
cout<<"序号\t选中物品\t总重量\t\t总价值\t\t能否装入"<<endl;
for(it=ps.begin();it!=ps.end();++it) //扫描ps中每一个集合元素
{
cout<<count+1<<"\t";
sumw=sumv=0;
cout<<"{";
for(sit=(*it).begin();sit!=(*it).end();++sit)
{
cout<<*sit;
sumw+=w[*sit-1]; //w数组下标从0开始
sumv+=v[*sit-1]; //v数组下标从0开始
}
cout<<"}\t\t"<<sumw<<"\t\t"<<sumv;
if(sumw<=W)
{
cout<<"\t\tcan"<<endl;
if(sumv>maxsumv) //比较求最优方案
{
maxsumw=sumw;
maxsumv=sumv;
maxi=count;
}
}
else
{
cout<<"\t\tno"<<endl;
}
count++; //方案编号增加1
}
cout<<"最佳方案为: ";
cout<<"选中物品";
cout<<"{ ";
for(sit=ps[maxi].begin();sit!=ps[maxi].end();++sit)
{
cout<<*sit<<" ";
}
cout<<"},";
cout<<"总重量:"<<maxsumw<<"总价值:"<<maxsumv<<"\n";
}
int main()
{
int n=7,W=15;
int w[]={2,3,5,7,1,4,1};
int v[]={10,5,15,7,6,18,3};
PSet(n);
cout<<"0/1背包的求解方案:"<<endl;
Knap(w,v,W);
return 0;
}