背包问题贪心法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
背包问题贪心法
实验报告
学院:计算机科学与技术学院班级:****
学号:****
姓名:****
一、实验目的
1)以背包问题为例,掌握贪心法的基本设计策略。
2)熟练掌握各种贪心策略情况下的背包问题的算法并实现;其中:量度标准分别取:效益增量P 、物品重量w 、P/w 比值;
3) 分析实验结果来验证理解贪心法中目标函数设计的重要性。
二、问题基本思想描述
(1)贪心法的基本思路
从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。
该算法存在问题:
1. 不能保证求得的最后解是最佳的;
2. 不能用来求最大或最小解问题;
3. 只能求满足某些约束条件的可行解的范围。
(2)背包问题的描述
已知有n 种物品和一个可容纳M 重量的背包,每种物品i 的重量为i
w 。假定将物品i 的一部分
i
x 放入背包就会得到
i
i x p 的效益,这里,
1
0≤≤i x ,
>i p 。
显然,由于背包容量是M ,因此,要求所有选中要装入背包的物品总重量不得超过M.。如果这n 件物品的总重量不超过M ,则把所有物品装入背包自然获得最大效益。现需解决的问题是,在这些物品重量的和大于M 的情况下,该如何装包,使得得到更大的效益值。由以上叙述,可将这个问题形式表述如下:
极 大 化目标函数
∑≤≤n
i i
x
p 1i
约束条件 M x w n i i ≤∑
≤≤1i
n
i w p x i i i ≤≤>>≤≤1,0,0,10
(3)用贪心策略求解背包问题
首先需确定最优的量度标准。这里考虑三种策略:
策略1:按物品价值p降序装包,
策略2:按物品重w升序装包
策略3:按物品价值与重量比值p/w的降序装包
(4)算法描述
以策略3为例:
procedure GREEDY-KNAPSACK(P,W,M,X,n)
//P(1:n)和W(1:n)分别含有按P(i)/W(i)≥P(i+1)/ W (i+1)排序的n件物品的效益值和重量。M是背包的容量,而X(1:n)是解向量。// real P(1:n),W(1:n),X(1:n),M,cu;
integer i,n;
X←0 //将解向量初始化为零
cu←M //cu是背包剩余容量
for i←1 to n do
if W(i)>cu then exit endif
X(i) ←1
cu←cu-W(i)
repeat
if i≤n then X(i) ←cu/W(i)
endif
end GREEDY-KNAPSACK
三、程序流程图
以策略三为例:(此时物品已经按物品价值与重量比值p/w降序排列)
四、以策略三为例程序清单
#include
#include
struct good
{
double v,w; //权值及重量
double x; //解向量
};
void cpygood(good a,good b){
a.v =
b.v;
a.w =
b.w;
a.x =
b.x;
}
void insertionsort(good *goods, int n){
int i,j;
good item;
for(j=1;j //cpygood(item, goods[j]); item.v = goods[j].v; item.w = goods[j].w; item.x = goods[j].x; i = j-1; while(item.v/item.w > goods[i].v/goods[i].w && i>=0) { //cpygood(goods[i+1], goods[i]); goods[i+1].v = goods[i].v; goods[i+1].w = goods[i].w; goods[i+1].x = goods[i].x; i--; } //cpygood(goods[i+1],item); goods[i+1].v = item.v; goods[i+1].w = item.w; goods[i+1].x = item.x; } } void greedy(int n, double c, good *goods) { //n为物品数量,c为背包能承受的重量double m = c; int i; insertionsort(goods,n); for(i=0;i goods[i].x = 0; for(i=0;i if(goods[i].w > m) break; goods[i].x = 1; m -= goods[i].w; } if(i < n) goods[i].x = m/goods[i].w; } void main(){ good *goods; int n,i; double c; freopen("goods.in","r",stdin); freopen("goods.out","w",stdout); scanf("%lf",&c); scanf("%d",&n); goods = (good *)malloc(n); for(i=0; i