算法设计与分析—背包问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法设计与分析
—背包问题
-
【问题描述】
给定n种物品和一个背包。物品i的重量是Wi,其价值为Vi,背包的容量为C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n。
【问题分析】
用贪心算法求解背包问题的步骤是,首先计算每种物品单位重量的价值vi/wi;然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总量未超过c,则选择单位重量价值次高的物品并尽可能多地装入背包。依此策略一直进行下去,直到背包装满为止。
【算法设计】
因可以取物体的部分放入,故每次选择价值重量比最高的物体放入,可保证放入的价值一定最大,满足贪婪选择性质和最有子结构性质,故采用贪心算法求解:
1. 根据各个物体的价值p与重量w计算价值重量比v
2. 根据v降序排序
3. 从当前最大的v的开始,判断该物体重量是否超过背包剩余载重
4. 是则放入背包剩余载重量的物体,加上这部分的价值,跳到7
5. 否则将物体完整放入背包,加上物体的价值
6. 若还有物体未放入背包,则跳到3
7. 输出背包中物体的总价值
【算法实现】
#include
struct goodinfo
{
float p; //物品效益
float w; //物品重量
float X; //物品该放的数量
int flag; //物品编号
};//物品信息结构体
void Insertionsort(goodinfo goods[],int n)
{//插入排序,按pi/wi价值收益进行排序,一般教材上按冒泡排序
int j,i;
for(j=2;j<=n;j++)
{
goods[0]=goods[j];
i=j-1;
while (goods[0].p>goods[i].p)
{
goods[i+1]=goods[i];
i--;
}
goods[i+1]=goods[0];
}
}//按物品效益,重量比值做升序排列
void bag(goodinfo goods[],float M,int n)
{
float cu;
int i,j;
for(i=1;i<=n;i++)
goods[i].X=0;
cu=M; //背包剩余容量
for(i=1;i { if(goods[i].w>cu)//当该物品重量大与剩余容量跳出break; goods[i].X=1; cu=cu-goods[i].w;//确定背包新的剩余容量 } if(i<=n) goods[i].X=cu/goods[i].w;//该物品所要放的量 /*按物品编号做降序排列*/ for(j=2;j<=n;j++) { goods[0]=goods[j]; i=j-1; while (goods[0].flag { goods[i+1]=goods[i]; i--; } goods[i+1]=goods[0]; } /////////////////////////////////////////// cout<<"最优解为:"< for(i=1;i<=n;i++) cout<<"第"< cout< } } void main() { cout<<"|--------运用贪心法解背包问题---------|"< int j,n; float M; goodinfo *goods;//定义一个指针 while(j) { cout<<"请输入物品的总数量:"; cin>>n; goods=new struct goodinfo [n+1];// cout<<"请输入背包的最大容量:"; cin>>M; cout< int i; for(i=1;i<=n;i++) { goods[i].flag=i; cout<<"请输入第"< cin>>goods[i].w; cout<<"请输入第"< cin>>goods[i].p; goods[i].p=goods[i].p/goods[i].w;//得出物品的效益,重量比 cout< } Insertionsort(goods,n); bag(goods,M,n); cout<<"press <1> to run agian"< cout<<"press <0> to exit"< cin>>j; }