贪心算法解决背包问题

时间:2023-01-19 04:23:04

问题重述:

与0-1背包问题类似,所不同的是,在选择物品i装入背包的时候,可以选择物品i的一部分装入背包,而不一定全部装入背包,这是与0-1背包问题的差别。形式化描述语言:给定背包容量c(c>0),和物品i的重量wi(wi>0)、价值vi(vi>0)。

要求找出一个n元向量(x1,x2,x3,...,xn),使得∑_(i=1)^n▒〖w_i x_i 〗≤c_(i=1)^n▒〖v_i x_i 〗

实例说明:

给定背包容量50Kg,物品信息:物品1,重量10Kg,价值60元;物品2,重量20Kg,价值100元;物品3,重量30Kg,价值120元。则贪心策略有三种:

1、先把价值高的装进去,这样来说,能够确保背包内物品价值的有效增长,但是背包容量消耗太快,不利于总体价值的最大化。

2、先把重量小的物品装进去,这种策略能确保背包内的空间得以有效的利用,但是背包内物品的价值却不能有效增长,即增长缓慢,也不利于总体价值的最大化。

3、以上两种策略只考虑到了背包价值的增长和背包容量的利用,都不利于背包内物品价值的最大化。不妨,给每件物品赋予权重=价值/重量,并且按照物品的权重降序排序,依次将物品装入背包。三种策略示意图如下:

贪心算法解决背包问题

代码和注释如下:

#include <iostream>
#include <algorithm>
#define MAX_NUM 1000
using namespace std;

struct Goods //info of goods定义物品信息结构体
{
int weight;// the weight of goods重量
int value;// the value of goods价值
double ValPerWei;// value per weight权重
double load; //物品装入背包的部分的系数(例如上图中物品全部装入则load为1,装入10/20则load为0.5)
};
int cmp( Goods const &a, Goods const &b)//定义sort函数的比较函数
{
if(a.ValPerWei<b.ValPerWei) return 0;
else return 1;
}
void Greedy(Goods g[],int good_num, int content)//贪心算法
{
for(int i=0; i<good_num; i++)
{
if(content>g[i].weight)//如果背包足够装下整个物品
{
content-=g[i].weight;
g[i].load=1;
}
else if(content>0){//如果背包不足以装下整个物品
g[i].load=(double)content/g[i].weight;//计算物品装入背包的部分
content=0;//背包容量置0
return;//程序结束,返回
}
}
}
int main()
{
int goods_num;
int bagvol;
double total_value=0;
double total_weight=0;
cout<<"Please input the volum of bag:"<<endl;
cin>>bagvol;
cout<<"Please input the number of goods:"<<endl;
cin>>goods_num;
Goods G[goods_num+1];
cout<<"Please inuput the weight and value of goods:"<<endl;
for(int i=0; i<goods_num; i++)
{
cin>>G[i].weight>>G[i].value;//输入重量价值
G[i].ValPerWei=(double)G[i].value/G[i].weight;//计算权重
G[i].load=0;//load置0
}

sort (G,G+goods_num,cmp);//sort by ValPerWei

Greedy(G,goods_num,bagvol);
cout<<"Info of loaded goods:"<<endl;
for(int i=0;i<goods_num;i++)//output the info of goods
{
if(G[i].load==0.0)break;//如果检测到物品未被装入背包,则推出循环

total_value+=(G[i].value*G[i].load);//装入背包的物品总价值
total_weight+=(G[i].weight*G[i].load);//装入背包的物品总重量
cout<<"weight: "<<G[i].weight<<" "<<"value: "<<G[i].value<<" "<<"the value per weight of good: "<<G[i].ValPerWei<<" the part of goods: "<<G[i].load<<endl;//输出装入背包的物品信息
}
cout<<"the volum of bag is: "<<bagvol<<endl;//输出背包容量
cout<<"the total weight is: "<<total_weight<<endl;//输出装入物品的总重量
cout<<"the total value is: "<<total_value<<endl;//输出装入物品的总价值
}