贪心算法:
(1) 给定n个物品,物品价值分别为P1,P2,…,Pn,物品重量分别W1,W2, …, Wn,背包容量为M。每种物品可部分装入到背包中。输出X1,X2,…,Xn,0<Xi<1, 使得 最大,且 <M。试设计一个算法求解该问题,分析算法的正确性.
解:
设计思路:首先将n个物品按单位价值从大到小排序,每次取剩余物品中单位价值最大的物品放入背包,若背包的容量足够则放入整个物品,否则放入物品的一部分。
最优子结构性质:
贪心选择性:
综上所述,该算法具有贪心选择性。
算法的源代码如下:
// Test.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#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;
Goods *G;
cout<<"请输入背包的容量:"<<endl;
cin>>bagvol;
cout<<"请输入商品的种类:"<<endl;
cin>>goods_num;
// Goods G[goods_num+1];
G= new Goods[goods_num+1];
cout<<"请输入商品的重量和价值:"<<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);
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<<"背包容量为: "<<bagvol<<endl;//输出背包容量
cout<<"装入物品的总重量为: "<<total_weight<<endl;//输出装入物品的总重量
cout<<"装入物品的最大价值为: "<<total_value<<endl;//输出装入物品的总价值
return 0;
}